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

41

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 ça se voit Error too many argument. Pourquoi?

taymindis Woon
la source
Vous devez fournir 1. la commande que vous appelez le script et 2. la sortie complète.
Lucio
2
Vous devriez utiliser [[ ]]. Sinon, vous devez citer vos variables.
Christophe De Troyer
Si $ 1 n'existait pas, alors $ 2 deviendrait $ 1, ce qui rendrait le test de $ 1 et $ 2 sans valeur tous les deux comme non pertinent.
WinEunuuchs2Unix
@ WinEunuuchs2Unix Pas nécessairement non pertinent - dans certains cas, vous voulez vous assurer qu'il y a réellement quelque chose au lieu d'une chaîne vide ou nulle dans les arguments. $1peut être non défini ou défini sur une chaîne nulle par l'utilisateur du script. Considérez cette séquence de commande: $ set '' baralors les echo "x${1}x";deux variables sont définies, mais l’une d’elles est nulle.
Sergiy Kolodyazhnyy

Réponses:

56

Essayez d’utiliser le test -z:

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

De l'homme bash:

-z string
   True if the length of string is zero.
Sylvain Pineau
la source
Ça marche pour moi!
pengisgood
il est intéressant de noter que la réponse la plus votée et acceptée ne répond pas réellement à la question posée.
mehmet
Lors de l'écriture de scripts de shell portables, cet indicateur doit être utilisé avec précaution, car sur certains systèmes Unix commerciaux, cet indicateur est défectueux. Voir ma réponse pour les sources liées.
Sergiy Kolodyazhnyy
14

Puisque ceci est étiqueté bash, je recommande que l’on utilise la construction de test étendue ( [[...]]) , et oublie les guillemets:

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

Sauf si vous optez pour shla compatibilité / POSIX, il n'y a aucune raison de ne pas l'utiliser [[ ]].

muru
la source
3

Ce qui suit fonctionne aussi,

if [ "$1" == "" && "$2" == ""]; then
    echo NULL
fi
Avinash Raj
la source
Les &&autres séparateurs de commandes logiques ne sont pas autorisés dans le classique test. Vous devez utiliser d'autres constructions de test à la place (comme -a, je pense)
muru
3

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 bashqui ne semble pas être le cas lors des tests :

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

Avec /bin/shqui est en fait un lien symbolique /bin/dashsur Ubuntu, une erreur est signalée comme suit:

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

Et les autonomes /bin/testaussi:

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

Sidenote: Si vous vous demandez ce qui est /usr/bin/testet pourquoi je suis en utilisant bashet sh, alors vous devriez savoir que [est alias pour la testcommande, 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 ifinstructions, elles agissent sur les statuts de sortie des commandes, d'où le pourquoi [et testsont 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 testcomprend. 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/shscripts. Il peut également être combiné comme dans

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

Bien sûr, nous pourrions utiliser le -zdrapeau. Toutefois, selon certaines recherches, notamment ksh88 (selon Stéphane Chazelas ), ce drapeau est défectueux.

Voir également

Sergiy Kolodyazhnyy
la source
+1 pour une approche très intéressante.
WinEunuuchs2Unix
@ WinEunuuchs2Unix Edited pour le rendre encore plus intéressant :)
Sergiy Kolodyazhnyy
1

Je pense que le titre de l'article n'est pas exact, car le message avait pour but 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 la même chose que 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 la même chose que vérifier s'il n'y a pas de paramètre:

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