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).