Recentemente, usei o comando echo prefixando-o com $. Para minha surpresa, o resultado foi um erro. Meu comando era algo parecido com este.
# !/bin/bash $(echo "a")
O erro foi ..
./test1.sh: line 3: a: command not found
Alguém pode explicar o que está acontecendo aqui. Agradecemos antecipadamente.
Resposta
$(echo a)
é uma “substituição de comando”. O $(...)
será substituído pela saída do comando em . A saída neste caso é a
, que o shell tenta executar. O shell não consegue localizar o comando chamado a
e você recebe a mensagem de erro.
Não está claro qual era sua intenção ou o que esperava que acontecesse . É muito incomum querer executar o resultado de uma substituição de comando.
Alguns programas produzem strings que devem ser avaliadas pelo shell. Portanto, é possível veja o código como
eval "$(ssh-agent)"
que avalia (executa) a saída de um determinado comando. Esses comandos têm uma saída estritamente especificada e geralmente são considerados seguros para serem executados neste forma. No exemplo acima, ssh-agent
iniciará o processo do agente SSH e produzirá alguns comandos que definirão as variáveis de ambiente apropriadas que ssh
o cliente posteriormente precisará usar o agente, por exemplo,
SSH_AUTH_SOCK=/tmp/ssh-Ppg1EO5eRIZp/agent.6017; export SSH_AUTH_SOCK; SSH_AGENT_PID=6018; export SSH_AGENT_PID; echo Agent pid 6018;
Isso é então avaliado por eval
.
eval
é usado aqui em vez de apenas simplesmente usando $(ssh-agent)
já que a saída do comando ssh-agent
é mais um comando composto. Sem eval
, os ;
terminadores de comando seriam especiais.
Exemplo:
$ s="echo hello; echo world" $ $s hello; echo world $ eval "$s" hello world
Comentários
Resposta
Você pode usar set -x
para veja o que o shell está fazendo:
set -x $(echo "a") ++ echo a + a
O shell executa echo a
e coloca a saída na linha de comando. É o mesmo que se você tivesse tentado executar esta linha de comando:
a
O shell procura um comando a
no caminho (e mesmo antes na função, alias e listas de hash), não o encontra e, portanto, gera um erro.
Funciona se a saída for um comando válido:
$(echo "ls")
Comentários
- você pode me dizer para que, na verdade, usamos $ other em vez de chamar uma variável.
- @Ashu Obviamente, também é usado para substituição de comandos – seu caso. Além disso, ele aparece na computação (
echo $((1+2+3))
), criação de string ($'foo\nbar'
/$"foo"
) e (menos relacionado ao shell) nas regexes quebash
entende ([[ foo =~ ^f..$ ]]
). Também é usado para modificar variáveis de várias maneiras:${foo#bar}
eval "$(dircolors)"
é uma coisa razoável a se fazer. Mesmo com vários outros comandos que seguem esse padrão, como gpg-agent.$(ssh-agent)
. Bom ponto.