web-dev-qa-db-fra.com

comment vérifier si $ 1 et $ 2 sont nuls?

J'exécute un script qui passe l'argument de chaîne et que je veux faire si l'instruction suivante est affichée comme ci-dessous:

if [ $1 != '' ] && [ $2 != '' ]
then 
    do something.....

mais il a montré Error too many argument. Pourquoi?

38
taymindis Woon

Essayez d’utiliser le test -z:

if [ -z "$1" ] && [ -z "$2" ]

De man bash:

-z string
   True if the length of string is zero.
52
Sylvain Pineau

Etant donné que cette balise porte la balise bashname__, je vous recommande d’utiliser la construction test étendu ([[...]]) et d’oublier les guillemets:

if [[ -z $1 && -z $2 ]]; then
...

Sauf si vous optez pour la compatibilité de shname __/POSIX, il n’ya aucune raison de ne pas utiliser [[ ]].

13
muru

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 qui, une fois testé dans bash, ne semble pas être le cas:

$ [ $1 != '' ] && [ $2 != '' ]
bash: [: !=: unary operator expected

Avec /bin/sh qui est en fait un lien symbolique vers /bin/dash sur Ubuntu, une erreur a été signalée comme suit:

$ sh
$ [ $1 != '' ] && [ $2 != '' ]
sh: 1: [: !=: unexpected operator

Et le /bin/test autonome aussi:

$ /usr/bin/test $1 != ''  
/usr/bin/test: missing argument after ‘’

Sidenote: Si vous vous demandez ce qu'est /usr/bin/test et pourquoi j'utilise bash et sh, vous devez savoir que [ est un alias pour la commande test, qui existe également en tant qu'exécutable autonome ou plus généralement - comme construit par Shell, chaque shell utilisera en premier. Quant aux instructions if, elles fonctionnent sur les statues de sortie des commandes. Par conséquent, [ et test sont des commandes, tout le reste étant des arguments pour ces commandes - un ordre incorrect de ces arguments de 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:

[ != '' ]

ce qui casse la syntaxe que 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 ce que Shell 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 vu dans les scripts /bin/sh. Il peut également être combiné comme dans

if [ "x${var1}${var2}" == "x" ]; then
    ...
fi

Bien sûr, nous pourrions utiliser le drapeau -z. Toutefois, selon les recherches effectuées sur certains shells, notamment ksh88 (selon Stephane Chazelas ), ce drapeau est défectueux.

Voir également

3
Sergiy Kolodyazhnyy

Ce qui suit fonctionne aussi,

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi
3
Avinash Raj

Je pense que le titre du message n’est pas exact, car l’intention dans le message était de vérifier si $ 1 et $ 2 ne sont pas nuls. L'exemple donné manquait simplement les guillemets doubles dans $ 1 et $ 2 pour fonctionner. Les variables doivent être doubles pour être développées lors de la comparaison de chaînes. Mais, vérifier si $ 1 et $ 2 existent est identique à vérifier si $ 2 existe, puisqu’il n’existera pas si $ 1 n’existe pas. La commande 'if' n'est également pas nécessaire dans ce cas, car 'test' renvoie vrai/faux et utilise '&&' comme 'alors' si return est 0/vrai:

[ "$2" != '' ] && commands...

Plus simple, avec -n (non nul):

[ -n "$2" ] && commands...

Pour "vérifier si $ 1 et $ 2 sont nuls" serait identique à vérifier s'il n'y a pas de paramètre:

[ $# -eq 0 ] && commands...
1
Guariba Som