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' .