Comentários
Resposta
" Substituição de comando " é o nome do recurso da linguagem shell que permite a você executar um comando e ter a saída desse comando substituir ( substitua) o texto do comando.
Não há nenhum outro recurso da linguagem shell que permita fazer isso.
Uma substituição de comando, ou seja, todo o $(...)
expressão, é substituído por sua saída, que é o principal uso das substituições de comando.
O comando que a substituição de comando executa é executado em um subshell, o que significa que tem seu próprio ambiente que não afetará o ambiente do shell pai.
Nem todas as execuções de subshell são substituições de comando, embora ugh (veja mais exemplos no final).
Exemplo mostrando que uma substituição de comando é executada em um subshell:
$ s=123 $ echo "hello $( s=world; echo "$s" )" hello world $ echo "$s" 123
Aqui, o a variável s
é definida para a string 123
. Na próxima linha, echo
é chamado em uma string contendo o resultado de uma substituição de comando. A substituição do comando define s
para a string world
e ecoa essa string. A string world
é a saída do comando na substituição do comando e, portanto, se foi executado em set -x
, veríamos que a segunda linha acima teria sido expandida para echo "hello world"
, que produz hello world
no terminal:
$ set -x $ echo "hello $( s=world; echo "$s" )" ++ s=world ++ echo world + echo "hello world" hello world
(bash
adiciona um nível extra de +
prompts para todos os níveis de um subshell de substituição de comando na saída de rastreamento, outros shells podem não fazer isso)
Por último, mostramos que o comando dentro do comando substitution foi executado em seu próprio subshell, porque não afetou o valor de s
no shell de chamada (o valor de s
ainda é 123
, não world
).
Existem outras situações em que os comandos são executados em subshells, como em
echo "hello" | read message
Em bash
, a menos que você defina a opção lastpipe
(apenas em instâncias não interativas), o read
é executado em um subshell, o que significa que $message
não será alterado no shell pai, ou seja, fazer echo "$message"
após o comando acima exibirá uma string vazia (ou qualquer valor $message
era antes).
Uma substituição de processo em bash
também é executada em um subshell:
cat < <( echo "hello world" )
Isso também é diferente de uma substituição de comando.
Comentários
- Para o bash 4.2 up, se shopt lastpipe estiver definido, o controle de trabalho não estiver ativo e o pipeline não estiver em segundo plano, o último comando não é executado em um subshell.
- Você diz: “Não há nenhum outro recurso da linguagem shell que permite que você faça isso.” Bem, correndo o risco de rachar os cabelos, você pode fazer
cmd₁ > myfile
/read -r var < myfile
/cmd₂ "$var"
. Se necessário, você pode expandir isso para lidar com dados de várias linhas. - @ G-Man Sim, e você também pode escrever um novo script de shell em um arquivo e executá-lo.Porém, não há outro recurso que forneça uma maneira de substituir um trecho de texto pela saída de um comando.
Resposta
a=$(command)
armazenará o valor do resultado de command
na variável.
Não há mais nada a fazer.
Como observação lateral, acredito:
a=`command`
foi descontinuado e tem o mesmo significado que acima.
Comentários
- resultado aqui é a saída padrão do comando sem toda a nova linha final caracteres (e algumas variações entre shells se a saída não for texto). Observe que
`...`
é o Bourne da sintaxe csh enquanto$(...)
é a sintaxe Korn / POSIX (com`...`
ainda com suporte para compatibilidade com versões anteriores) - @St é phaneChazelas Obrigado por informações valiosas e fique à vontade para editar a resposta para incluí-las.
echo
é um mau exemplo de substituição de comando porque 1) a saída teria sido exibida de qualquer maneira, 2)printf
é mais seguro para usar para dados variáveis. O exemplo também poderia ser escritodate | sed 's/^/Today is /'
printf
) é inútil. Mudei um pouco a expressão, de imediatamente parasometime later
, é mais atraente?thedate=$(date)
, seguido porprintf 'The date is %s\n' "$thedate"
.