Você não passa argumentos citados para um comando, você passa argumentos.
Quando você entra:
cmd arg1 arg2
O shell analisa essa linha em sua própria sintaxe, em que space é um delimitador de palavras e chama cmd1
com cmd
, arg1
e arg2
como argumentos.
Nota : cmd
não recebe nenhum caractere de espaço em seus argumentos, os espaços são apenas operadores na sintaxe da linguagem shell.
Como quando em C, você escreve func("foo", "bar")
, em tempo de execução, func
recebe dois argumentos de ponteiro, ele não vê nenhum caractere (
ou ,
ou "
ou espaço.
Também parte da sintaxe do shell está citando. "
é usado para ter palavras que contenham caracteres que fazem parte da sintaxe do shell.
Quando você faz:
cmd "arg 1" arg2
cmd
recebe cmd
, arg 1
e arg2
como argumentos. Não vê nenhum caractere "
. Esses "
são usados para evitar que o espaço seja tratado como um separador de palavras na sintaxe do shell.
Agora, quando você faz:
cmd $VAR
não é o mesmo que fazer:
cmd the content of the variable
Se fosse, você teria problemas com:
VAR='foo; reboot'
echo $VAR
por exemplo.
No shell parecido com o Bourne, o conteúdo de $VAR
não é passado textualmente como um único argumento para cmd
(infelizmente; ele foi corrigido em alguns outros shells como rc
, es
, fish
e, em menor grau, zsh
). Em vez disso, está sujeito a divisão e globbing ( split+glob
) e as palavras resultantes são passadas para cmd
.
A divisão é feita com base nos caracteres na variável especial $IFS
, por espaço padrão, tabulação e nova linha.
Para o $ARGUMENTS
, que contém -executors 1 -description "The Host"
, está dividindo em -executors
, 1
, -description
, "The
e Host"
. Como nenhuma dessas palavras contém caractere curinga, a parte glob não se aplica, portanto, essas palavras são passadas para cmd
.
Aqui, você pode usar o operador split+glob
e usar como separador para a parte de divisão um caractere que não aparece nessas palavras:
ARGUMENTS='-executors|1|-description|The Host'
IFS='|'
cmd $ARGUMENTS
Ou melhor, para shells que os suportam (como bash
), use matrizes , onde você pode ter uma variável que contenha todos esses argumentos.
eval
é avaliar o código do shell. Portanto, a outra opção é ter ARGUMENTS
contendo código shell (texto na sintaxe do shell, em oposição a uma lista de argumentos), e ter passado para eval
para interpretação. Mas lembre-se de citar a variável para evitar o operador split + glob:
eval "cmd $ARGUMENTS"