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'tse tornadon'\''t) - Adicione
'no início de cada argumento e também no final de cada argumento. (por exemplo, dedon't,don'\''tse 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.)