J'ai besoin de vérifier l'existence d'un argument d'entrée. J'ai le script suivant
if [ "$1" -gt "-1" ]
then echo hi
fi
Je reçois
[: : integer expression expected
Comment vérifier d'abord l'argument d'entrée1 pour voir s'il existe?
J'ai besoin de vérifier l'existence d'un argument d'entrée. J'ai le script suivant
if [ "$1" -gt "-1" ]
then echo hi
fi
Je reçois
[: : integer expression expected
Comment vérifier d'abord l'argument d'entrée1 pour voir s'il existe?
Réponses:
C'est:
if [ $# -eq 0 ]
then
echo "No arguments supplied"
fi
La $#
variable vous indiquera le nombre d'arguments d'entrée auxquels le script a été transmis.
Ou vous pouvez vérifier si un argument est une chaîne vide ou non:
if [ -z "$1" ]
then
echo "No argument supplied"
fi
Le -z
commutateur testera si l'expansion de "$ 1" est une chaîne nulle ou non. S'il s'agit d'une chaîne nulle, le corps est exécuté.
exit 1
à la fin de vos échos à l'intérieur du bloc if lorsque l'argument est requis pour que le script fonctionne. Évident, mais mérite d'être noté pour être complet.
programname "" secondarg third
. La $#
vérification vérifie sans ambiguïté le nombre d'arguments.
if [ ! -z "$1" ]; then ...
Il vaut mieux démontrer de cette façon
if [[ $# -eq 0 ]] ; then
echo 'some message'
exit 1
fi
Vous devez normalement quitter si vous avez trop peu d'arguments.
exit 1
que vous voulez habituellement et utilise le [[ ]]
test qui (iirc) est généralement plus raisonnable. Donc, pour les gens, copier-coller aveuglément du code est la meilleure réponse.
Dans certains cas, vous devez vérifier si l'utilisateur a passé un argument au script et sinon, revenir à une valeur par défaut. Comme dans le script ci-dessous:
scale=${2:-1}
emulator @$1 -scale $scale
Ici, si l'utilisateur n'a pas passé scale
comme 2ème paramètre, je lance l'émulateur Android -scale 1
par défaut. ${varname:-word}
est un opérateur d'expansion. Il existe également d'autres opérateurs d'expansion:
${varname:=word}
qui définit l'indéfini varname
au lieu de renvoyer la word
valeur;${varname:?message}
qui retourne varname
s'il est défini et n'est pas nul ou imprime le message
et abandonne le script (comme le premier exemple);${varname:+word}
qui word
ne renvoie que si varname
est défini et n'est pas nul; renvoie null sinon.${varname?message}
. Le supplément est-il :
une faute de frappe ou change-t-il de comportement?
: ${1?"First argument is null"} ${2?"Please provide more than 1 argument"}
Essayer:
#!/bin/bash
if [ "$#" -eq "0" ]
then
echo "No arguments supplied"
else
echo "Hello world"
fi
$#
et 0
?
else
aussi.
foo*
) et le fractionnement des mots (c'est-à-dire le fractionnement du contenu si la valeur contient des espaces). Dans ce cas, il n'est pas nécessaire de citer $#
car ces deux cas ne s'appliquent pas. Il 0
n'est pas non plus nécessaire de citer le, mais certaines personnes préfèrent citer des valeurs car ce sont vraiment des chaînes et cela le rend plus explicite.
Une autre façon de détecter si des arguments ont été passés au script:
((!$#)) && echo No arguments supplied!
Notez que (( expr ))
l'expression est évaluée selon les règles de Shell Arithmetic .
Pour sortir en l'absence d'arguments, on peut dire:
((!$#)) && echo No arguments supplied! && exit 1
Une autre façon (analogue) de dire ce qui précède serait:
let $# || echo No arguments supplied
let $# || { echo No arguments supplied; exit 1; } # Exit if no arguments!
help let
dit:
let: let arg [arg ...]
Evaluate arithmetic expressions. ... Exit Status: If the last ARG evaluates to 0, let returns 1; let returns 0 otherwise.
exit
qui tue mon processus zsh, j'utilise return
ce qui ne le tue pas
((!$#))
déclencherait une substitution de l'histoire?
Seulement parce qu'il y a un point de base plus à souligner, j'ajouterai que vous pouvez simplement tester que votre chaîne est nulle:
if [ "$1" ]; then
echo yes
else
echo no
fi
De même, si vous attendez le nombre d'arguments, testez votre dernier:
if [ "$3" ]; then
echo has args correct or not
else
echo fixme
fi
et ainsi de suite avec tout arg ou var
Si vous souhaitez vérifier si l'argument existe, vous pouvez vérifier si le nombre d'arguments est supérieur ou égal à votre numéro d'argument cible.
Le script suivant montre comment cela fonctionne
#!/usr/bin/env bash
if [ $# -ge 3 ]
then
echo script has at least 3 arguments
fi
produit la sortie suivante
$ ./test.sh
~
$ ./test.sh 1
~
$ ./test.sh 1 2
~
$ ./test.sh 1 2 3
script has at least 3 arguments
$ ./test.sh 1 2 3 4
script has at least 3 arguments
En tant que petit rappel, les opérateurs de test numériques dans Bash ne fonctionnent que sur des entiers ( -eq
, -lt
,-ge
, etc.)
J'aime m'assurer que mes $ vars sont des pouces par
var=$(( var + 0 ))
avant de les tester, juste pour me défendre contre l'erreur "[: arg entier requis".
var=$(printf "%.0f" "$var")
peut gérer les flottants mais souffre de la sortie non nulle quand on lui donne une chaîne. Si cela ne vous dérange pas awk, cette méthode utilisation I semble être le plus robuste pour faire respecter un entier: var=$(<<<"$var" awk '{printf "%.0f", $0}')
. Si var n'est pas défini, il est par défaut "0". Si var est un flottant, il est arrondi à l'entier le plus proche. Les valeurs négatives sont également très bien à utiliser.
une validation de fonction bash liner
myFunction() {
: ${1?"forgot to supply an argument"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
ajouter le nom et l'utilisation de la fonction
myFunction() {
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"}
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
ajouter une validation pour vérifier si un entier
pour ajouter une validation supplémentaire, par exemple pour vérifier si l'argument passé est un entier, modifiez la validation d'une ligne pour appeler une fonction de validation:
: ${1?"forgot to supply an argument ${FUNCNAME[0]}() Usage: ${FUNCNAME[0]} some_integer"} && validateIntegers $1 || die "Must supply an integer!"
puis, construisez une fonction de validation qui valide l'argument, renvoyant 0 en cas de succès, 1 en cas d'échec et une fonction die qui abandonne le script en cas d'échec
validateIntegers() {
if ! [[ "$1" =~ ^[0-9]+$ ]]; then
return 1 # failure
fi
return 0 #success
}
die() { echo "$*" 1>&2 ; exit 1; }
Encore plus simple - utilisez simplement set -u
set -u
s'assure que chaque variable référencée est définie lors de son utilisation, il suffit donc de la définir et de l'oublier
myFunction() {
set -u
if [ "$1" -gt "-1" ]; then
echo hi
fi
}
[ -z "$1" ] && echo "No argument supplied"
Je préfère les monolignes, car elles sont plus faciles pour moi; et il est également plus rapide de vérifier la valeur de sortie par rapport à l'utilisationif