"Substituição de comando" é o nome do recurso da linguagem shell que permite executar um comando e fazer com que a saída desse comando substitua (substitua) o texto do comando.
Não há outro recurso da linguagem de shell que permita que você faça isso.
Uma substituição de comando, ou seja, toda a expressão $(...)
, é substituída por sua saída, que é o principal uso de substituições de comandos.
O comando que a substituição do comando executa é executado em um subshell, o que significa que possui seu próprio ambiente que não afetará o ambiente do shell pai.
Nem todas as execuções subshell são substituições de comandos (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, a variável s
é definida como a string 123
. Na próxima linha, echo
é invocado em uma string contendo o resultado de uma substituição de comando. A substituição de comando define s
como a string world
e ecoa essa string. A string world
é a saída do comando na substituição de comandos e, portanto, se isso fosse 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 +
para todos os níveis de uma sub-rotina de substituição de comandos na saída de rastreio, outras camadas podem não fazer isso)
Por último, mostramos que o comando dentro da substituição do comando foi executado em sua própria sub-rede, 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
, o read
é executado em uma subshell, o que significa que $message
não será alterado no shell pai, isto é, fazer echo "$message"
após o comando acima irá ecoar uma string vazia (ou qualquer outra valor $message
foi antes).
Uma substituição de processo em bash
também é executada em um subnível:
cat < <( echo 'hello world' )
Isso também é diferente de uma substituição de comando.