Que problema / padrão justifica usando a substituição de comando?

1

Criei alguns ambientes de servidor com o Ubuntu e o Bash, em provedores de hospedagem "autogerenciados" como o DigitialOcean, no qual eu rodava aplicativos Drupal / WordPress.

Durante todo esse tempo eu não tive necessidade de usar o que é chamado " sub-comando de comando ".

Eu pergunto, o que será um problema, um "padrão" no qual um programador do Bash teria que usar este conceito? Por favor, dê um exemplo?

    
por user9303970 10.06.2018 / 20:05

5 respostas

2

Eu uso com find , como:

tar cvf ../junk.tar 'find .'

Além disso, como parte do IDE de um homem pobre:

vi 'grep mysearcstring *.[ch]'

Os exemplos acima são de linha de comando. Eu também uso muito scripts, e seria pressionado sem ele. O caso mais comum é, provavelmente, como mencionado acima, para definir as variáveis do shell a partir da saída de um comando:

NOW='date'

Eu uso aspas por antigo hábito, mas a sintaxe $(command) é muito melhor, pois você pode incorporar uma dentro da outra. Com citações anteriores, você precisa saber exatamente onde colocar os caracteres de escape \ e isso é um incômodo.

    
por 11.06.2018 / 22:38
5

A substituição de comandos significa executar um comando shell e armazenar sua saída em uma variável ou exibir novamente usando o comando echo. Por exemplo, exibir data e hora:

echo "Today is $(date)"

É útil em situações em que meu comando recebe como parâmetro a saída de outro comando ou exemplo.

    
por 10.06.2018 / 20:09
4

De subseção Substituição de Comando no padrão POSIX :

Command substitution allows the output of a command to be substituted in place of the command name itself.

As substituições de comandos permitem uma maneira prática de fazer uso da saída de um comando sem a necessidade de primeiro gravá-lo em um arquivo temporário e, em seguida, lê-lo a partir desse arquivo. Isso é feito melhor se a saída do comando for uma string curta em uma única linha.

Algumas pessoas usam substituições de comando para coletar a saída de um comando, embora a quantidade de saída possa ser um documento de várias linhas. Isso geralmente não é uma boa maneira de usar a substituição de comandos. Em vez disso, o idioma padrão do Unix de passar dados entre estágios de processamento usando pipelines ou arquivos temporários deve ser usado.

Exemplos de substituições de comandos que eu uso:

Por exemplo, para descobrir se o usuário atual está executando o script como root:

if [ "$( id -u )" -ne 0 ]; then
   echo 'This script requires root privileges, re-run with sudo' >&2
   exit 1
fi

A substituição do comando $(id -u) será substituída pela saída de id -u , que retornará o UID (um inteiro) do usuário atual.

Outro exemplo. Estou usando o GnuPG para assinar git commits. Para o GnuPG funcionar corretamente, eu preciso definir GPG_TTY para o nome do dispositivo de terminal atual no arquivo de inicialização do meu shell interativo. Eu faço isso com

export GPG_TTY="$( tty )"

Isso define GPG_TTY para algo como /dev/ttyp4 dependendo do que o dispositivo de terminal atual está na sessão do shell.

Outro exemplo. Eu tenho um script que tem que tratar a execução em uma máquina Solaris como um caso especial:

case "$( uname -s )" in
    SunOS)
        # code specific for Solaris
        ;;
    *)
        # code for all other Unix platforms
esac

Outro exemplo. O comando getconf PATH retorna o "caminho padrão" para o sistema atual. Eu o uso em algumas circunstâncias para redefinir a variável PATH para um valor padrão "sane":

PATH="$( getconf PATH )"
    
por 10.06.2018 / 22:32
2

Outro exemplo:

  • No Docker, você pode limpar contêineres parados usando:

    docker rm containerID containerID containerID ...'
    
  • Você também pode obter os IDs dos contêineres que pararam de executar:

    docker ps -q -f "status=exited" 
    
  • Para que você possa limpar todos os contêineres interrompidos com:

    docker rm $(docker ps -q -f "status=exited")
    

... onde os ids produzidos por docker ps são substituídos pela string $(docker ps...) a ser usada pelo comando docker rm .

    
por 11.06.2018 / 00:27
1

O padrão de implementação que torna esse uso necessário é que os shells Unix executem cada comando não embutido em um processo filho. O processo filho não pode modificar o contexto de seu pai. A substituição de comandos pode fazer com que o shell use a saída textual de um comando não incorporado como se tivesse sido escrito no script de shell ou digitado na linha de comando.

    
por 12.06.2018 / 01:00