Eu escrevi um script que pode gerar esses argumentos para mim, com aspas
Se a saída for citada corretamente para o shell e você confiar na saída , poderá executá eval-lo.
Supondo que você tenha um shell que suporte matrizes, seria melhor usar um para armazenar os argumentos obtidos.
Se ./gen_args.shproduzir saída como 'foo bar' '*' asdf, então poderíamos executar eval "args=( $(./gen_args.sh) )"para preencher uma matriz chamada argscom os resultados. Isso seria os três elementos foo bar, *, asdf.
Podemos usar "${args[@]}"como de costume para expandir os elementos da matriz individualmente:
$ eval "args=( $(./gen_args.sh) )"
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
(Observe que as aspas. Se "${array[@]}"expandem para todos os elementos como argumentos distintos, sem modificação. Sem aspas, os elementos da matriz estão sujeitos à divisão de palavras. Veja, por exemplo, a página Matrizes no BashGuide .)
No entanto , evalé possível executar com êxito quaisquer substituições de shell, portanto $HOME, a saída seria expandida para o diretório inicial e uma substituição de comando realmente executaria um comando no shell em execução eval. Uma saída de "$(date >&2)"criaria um único elemento vazio da matriz e imprimiria a data atual no stdout. Isso é preocupante se gen_args.shobtém os dados de alguma fonte não confiável, como outro host na rede, nomes de arquivos criados por outros usuários. A saída pode incluir comandos arbitrários. (Se get_args.shele era malicioso, não precisaria produzir nada, apenas poderia executar os comandos maliciosos diretamente.)
Uma alternativa à citação de shell, que é difícil de analisar sem avaliação, seria usar algum outro caractere como separador na saída do seu script. Você precisaria escolher um que não seja necessário nos argumentos reais.
Vamos escolher #e ter a saída do script foo bar#*#asdf. Agora, podemos usar a expansão de comando sem aspas para dividir a saída do comando nos argumentos.
$ IFS='#' # split on '#' signs
$ set -f # disable globbing
$ args=( $( ./gen_args3.sh ) ) # assign the values to the array
$ for var in "${args[@]}"; do printf ":%s:\n" "$var"; done
:foo bar:
:*:
:asdf:
Você precisará IFSvoltar mais tarde se depender da divisão de palavras em algum lugar do script ( unset IFSdeve funcionar para torná-lo o padrão) e também usar set +fse quiser usar globbing mais tarde.
Se você não estiver usando o Bash ou algum outro shell que possua matrizes, use os parâmetros posicionais para isso. Substitua args=( $(...) )por set -- $(./gen_args.sh)e use em "$@"vez "${args[@]}"disso. (Também aqui você precisa de aspas "$@", caso contrário, os parâmetros posicionais estão sujeitos à divisão de palavras.)
evalpossa ser usado, mas geralmente não é recomendado.xargsé algo a considerar também