O seguinte produz uma bash: test: too many arguments
exceção em test
, com status de saída 2:
v='>'
test -n "$v" -a yes '!=' no # bash: test: too many arguments
echo $? # 2
test -n '>' -a 1 -eq 1 # bash: test: too many arguments
echo $? # 2
[ -n '>' -a 1 -eq 1 ] # bash: [: too many arguments
echo $? # 2
[[ -n '>' -a 1 -eq 1 ]]
# bash: syntax error in conditional expression
# bash: syntax error near `-a'
echo $? # 2
Ele funciona sem o -a e, como tal, funciona usando && em vez do -a:
v='>'
test -n "$v"
echo $? # 0
[ -n "$v" ]
echo $? # 0
test -n "$v" && test yes '!=' no
echo $? # 0
[ -n "$v" ] && [ yes '!=' no ]
echo $? # 0
Não há menção a esse comportamento peculiar na documentação: https://www.gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html#index-test
Versões conhecidas afetadas: GNU bash, versão 5.2.37(1)-release (x86_64-apple-darwin22.6.0) GNU bash, versão 3.2.57(1)-release (x86_64-apple-darwin22)
Se esse for o comportamento pretendido, qual é a solução alternativa adequada?
- Devo sempre usar
&&
em vez de-a
? - Devo usar uma substituição de parâmetro? por exemplo
test -n "${v//>/.}" -a 1 -eq 1
- Existe alguma outra sugestão?
Com base na documentação, isso parece um bug, mas não tenho uma explicação. (
'<'
também causa isso.)No entanto, eu tenho uma solução alternativa. Trocar as expressões funciona, assumindo que a ordem delas não é significativa:
No final das contas, é melhor usar o
&&
formato — veja esta resposta para “A negação de -a (o arquivo existe) no Bash não altera o resultado, enquanto para ! -e altera o resultado” ou esta resposta para “Qual é a diferença de -a e -e nas expressões condicionais do Bash?” para mais detalhes.