Quando você faz isso (parafraseando seu exemplo mais curto no comentário):
mkdir "foo bar"
parms="-l 'foo bar'"
ls $parms
A variável parms
é divisão de palavras ao longo de qualquer espaço em branco, sem considerar as cotações, torna-se assim
-l
, 'foo
e bar'
(três argumentos).
O exemplo original teve o mesmo problema com attr_marksweep_threadcount
e terminou com um dos argumentos contendo java.lang:type=GarbageCollector,name='PS
e o resto da string citada em outro argumento. Eu suponho que seu java não gostou disso.
Se citarmos a variável que contém os parâmetros:
ls "$parms"
Recebemos ls
chamado com -l 'foo bar'
(um argumento). Citar a variável impede a divisão de palavras (e a globalização de nomes de arquivos), mas aspas dentro da variável não.
É um pouco difícil contornar esse problema com variáveis de shell simples, mas como o Bash tem matrizes , você poderia usar um e colocar cada argumento em um elemento separado da matriz:
array=("-l" "foo bar")
ls "${array[@]}"
"${array[@]}"
se expande para o equivalente a todos os membros da matriz, citados individualmente.
Com shells sem array, você precisa usar algumas soluções. Os parâmetros posicionais podem ser expanded com $@
da mesma forma que as matrizes:
set -- "-l" "foo bar"
ls "$@"
Ou, como a divisão de palavras é feita somente ao longo dos caracteres definidos em IFS
, podemos dividir o shell em algo diferente de espaço em branco.
IFS=#
parms='-l#foo bar'
ls $parms
# though IFS stays set to the hash sign after this
A saída de bash -x
em seu exemplo tenta mostrar o que acontece, mas desde que ele tenta mostrar em aspas simples uma string contendo um aspas simples, a saída é um pouco confusa. Este:
%código%
analisa como 'java.lang:type=GarbageCollector,name='\''PS'
, 'java.lang:type=GarbageCollector,name='
e \'
todos concatenados juntos, ou seja, duas cadeias de caracteres com aspas simples e uma aspa simples entre aspas. Que parece mais bonito entre aspas duplas: 'PS'
.