Pour l'ancienne version de la réponse, voir la deuxième partie de cette réponse. Si vous voulez connaître les détails, lisez la suite
La cause du problème
Dans la question elle-même, il est rapporté que OP voit too many arguments error
, ce bash
qui ne semble pas être le cas lors des tests :
$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected
Avec /bin/sh
qui est en fait un lien symbolique /bin/dash
sur Ubuntu, une erreur est signalée comme suit:
$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator
Et les autonomes /bin/test
aussi:
$ /usr/bin/test $1 != ''
/usr/bin/test: missing argument after ‘’
Sidenote: Si vous vous demandez ce qui est /usr/bin/test
et pourquoi je suis en utilisant bash
et sh
, alors vous devriez savoir que [
est alias pour la test
commande, qui existe également exécutable autonome ou plus communément - comme shell intégré qui est ce que chaque coquille utilisera d' abord . En ce qui concerne les if
instructions, elles agissent sur les statuts de sortie des commandes, d'où le pourquoi [
et test
sont des commandes, tout le reste étant des arguments pour ces commandes - un ordre incorrect de ces arguments en ligne de commande entraîne des erreurs.
Retour au sujet: on ne sait pas comment OP a obtenu l'erreur sans rapport. Cependant, dans les 3 cas, le problème est le même: les variables non définies sont traitées comme des vides. Par conséquent, ce que le shell voit avec ces variables non précisées est:
[ != '' ]
qui casse la syntaxe qui test
comprend. Vous souvenez-vous de ce que j'ai dit à propos de l'ordre incorrect des arguments en ligne de commande? D'où l'importance de citer. Activons la sortie de diagnostic et voyons quel shell s'exécute:
$ set -x
# throws error
$ [ $1 != '' ] && [ $2 != '' ]
+ '[' '!=' '' ']'
bash: [: !=: unary operator expected
# no error
$ [ "$1" != '' ] && [ "$2" != '' ] || echo null vars
+ '[' '' '!=' '' ']'
+ echo null vars
null vars
Meilleure façon de tester les variables non définies
Une approche très fréquente que vous voyez autour est la suivante:
if [ "x$var1" == "x" ] && [ "x$var2" == "x" ];
then
echo "both variables are null"
fi
Pour citer Gilles :
Dans ["x $ 1" = "x"], le préfixe x garantit que x "$ 1" ne peut pas ressembler à un opérateur. Le shell ne peut donc analyser ce test qu'en traitant = comme un opérateur binaire.
Vraisemblablement, cela devrait être assez portable puisque je les ai vus dans des /bin/sh
scripts. Il peut également être combiné comme dans
if [ "x${var1}${var2}" == "x" ]; then
...
fi
Bien sûr, nous pourrions utiliser le -z
drapeau. Toutefois, selon certaines recherches, notamment ksh88 (selon Stéphane Chazelas ), ce drapeau est défectueux.
Voir également