Se você tiver controle sobre o programa wrapper, certifique-se de que ele não invoque uma subshell. No fundo, uma instrução para executar um programa consiste no caminho completo (absoluto ou relativo ao diretório atual ) para o executável e uma lista de strings para passar como argumentos. A pesquisa PATH, espaço em branco separando argumentos, citando e controlando operadores são todos fornecidos pelo shell. Sem casca, sem dor.
Por exemplo, com um wrapper Perl, use o formulário de lista de exec
ou system
. Em muitos idiomas, chame uma das funções exec
ou execXXX
(ou unix.exec
ou o que for chamado) em vez de system
ou os.spawn
com shell=False
ou o que for necessário.
Se o wrapper for um script de shell, use "$@"
para passar os argumentos, por exemplo,
#!/bin/sh
mysim -preset-opt "$@"
Se você não tem escolha e o programa invólucro invoca um shell, você precisará citar os argumentos antes de passá-los para o shell. A maneira fácil de citar argumentos é fazer o seguinte:
- Em cada argumento, substitua cada ocorrência de
'
(aspas simples) pela string de quatro caracteres'\''
. (por exemplo,don't
se tornadon'\''t
) - Adicione
'
no início de cada argumento e também no final de cada argumento. (por exemplo, dedon't
,don'\''t
se torna'don'\''t'
) - Concatene os resultados com um espaço entre eles.
Se você precisar fazer isso em um wrapper de shell, aqui está uma maneira.
arguments='-preset-opt'
for x; do
arguments="$arguments '"
while case $x in
*\'*) arguments="$arguments${x%%\'*}'\''"; x=${x#*\'};;
*) false;; esac
do :; done
arguments="$arguments$x'"
done
(Infelizmente, a construção ${VAR//PATTERN/REPLACEMENT}
do bash, que deve ser útil aqui, requer uma cotação peculiar, e eu não acho que você possa obter '\''
como o texto de substituição.)