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?
Essayez d’utiliser le test -z:
if [ -z "$1" ] && [ -z "$2" ]
De man bash
:
-z string
True if the length of string is zero.
Etant donné que cette balise porte la balise bash
name__, 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 sh
name __/POSIX, il n’ya aucune raison de ne pas utiliser [[ ]]
.
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
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
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.
Ce qui suit fonctionne aussi,
if [ "$1" == "" && "$2" == ""]; then
echo NULL
fi
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...