Quando você deixa uma expansão variável sem aspas, ela passa por divisão de palavras e expansão de nome de arquivo (ou seja, globbing). Não é analisado como um comando shell. Em geral, quando você constrói dinamicamente um fragmento de shell para executar, o caminho certo para executá-lo é eval "$a"
, em que a
contém a string para analisar como código de shell.
Em seu primeiro snippet, o valor de a
é a string my_cmd --verbose
. A divisão de palavras divide-a em duas palavras my_cmd
e --verbose
. Globbing não faz nada, pois não há curingas em nenhuma das palavras. O comando resultante da expansão de $a
consiste em duas palavras my_cmd
e --verbose
, então o comando my_cmd
(que pode ser um alias, uma função, um builtin ou um executável no PATH) é executado com o único argumento --verbose
.
No segundo snippet, as coisas são semelhantes, com três palavras resultantes da expansão: URL=myurl
, my_cmd
e --verbose
. Isso resulta em uma tentativa de executar o comando URL=myurl
com dois argumentos.
O comando shell URL=myurl my_cmd --verbose
é analisado de forma diferente: a primeira palavra é analisada como uma atribuição à variável URL
e, como há um nome de comando após ela, a atribuição define a variável de ambiente apenas pela duração do comando. . Isso faz parte da análise, não de algo que é feito após a expansão, portanto, para que o sinal de igual faça parte do código-fonte do shell, o sinal de igual não pode ser o resultado de alguma expansão.
Não armazene um comando com parâmetros em uma string . Use uma matriz. Para um comando complexo, como aquele em que você define variáveis ou executa o redirecionamento, além de executar o comando, use uma função, se possível, e, se não, use eval
(tomando muito cuidado com as citações adequadas).