Je compte utiliser la variable ci-dessous dans mon script bash, mais dans le cas où elle est vide ou nulle, quel serait le meilleur moyen de la gérer et de sortir du script.
tag=$1
Je vois des réponses avec 'set -u'. Je sais que cela fonctionnera, mais est-ce bon pour l'environnement de production?
Il existe un opérateur intégré pour exiger qu'une variable soit définie. Cela entraînera la fermeture du script si ce n'est pas le cas.
tag=${1?Need a value}
Généralement, ceci est utilisé avec le :
no-op au début du script.
: ${1?Need a value}
La fusion de "non défini ou vide" est quelque peu différente. Il n'y a pas de construction similaire pour sortir sur une valeur vide mais définie, mais vous pouvez facilement utiliser la syntaxe associée, ${var:-default}
, qui se développe en $var
si elle est définie et non vide, et default
sinon. Il existe également ${var-default}
qui ne produit default
que si la variable est correctement définie.
Cela peut être particulièrement utile lorsque vous voulez utiliser set -u
mais que vous devez gérer une variable éventuellement non définie:
case ${var-} in '') echo "$0: Need a value in var" >&2; exit 1;; esac
Je préfère un peu case
à if [ "${var-}" = '' ]
, principalement parce que cela me évite d'avoir à entourer les guillemets doubles autour de ${var-}
et le casse-tête d'une valeur dans $var
qui est interprétée comme une option à [
et vous envoie un message d'erreur lorsque vous vous y attendez le moins. (Dans Bash, [[
n'a pas ces problèmes; mais je préfère m'en tenir à POSIX Shell quand je le peux.)
Si vous voulez vérifier qu'une variable est non vide, procédez comme suit:
if [ -z "$tag" ]; then
exit 1
fi
Du manuel pour test
:
-z STRING
la longueur de STRING est nulle
Étant donné que vous utilisez les arguments de position du script, vous pouvez également tester le nombre d'arguments que vous recevez en examinant $#
.
Personne n'a suggéré l'option :?
.
Si vous voulez vous assurer que la variable est définie et non nulle:
SEARCH_PATH=${DAYS_TO_KEEP:?Must provide DAYS_TO_KEEP.}
Quittera immédiatement avec le code 2 et imprimera un message:
/entrypoint.sh: line 17: SEARCH_PATH: Must provide DAYS_TO_KEEP.
Je ne sais pas si vous voulez détecter si une variable est unset
ou empty
. Ce sont 2 choses différentes. Plus précisément, une variable peut être définie mais être vide:
$ var=""
$ if [ -z "$var" ]; then echo empty; fi
$ empty
La même chose se passe ici:
#!/usr/bin/env bash
set -u
echo $1
Tester:
$ ./test.sh
./test.sh: line 4: $1: unbound variable
$ ./test.sh ""
$
Ou ici:
#!/usr/bin/env bash
tag=${1?Need a value}
echo $tag
Tester:
$ ./se.sh
./se.sh: line 3: 1: Need a value
$ ./se.sh ""
$
D'autres affiches ont présenté des méthodes correctes pour détecter une variable non définie et vide. Personnellement, j'aime bien cette façon de détecter les variables vides et non définies:
#!/usr/bin/env bash
if [ "$1"A = A ]
then
echo variable is empty or unset
fi
Tester:
$ ./empty.sh ""
variable is empty or unset
$ ./empty.sh
variable is empty or unset
$ ./empty.sh 1
$
J'ai plutôt aimé comment Perl utilise "die" et il est facile de faire quelque chose de similaire dans Shell.
# Print (optional) error message and exit
# Usage: die [[msg] exit_status]
die() {
[[ -n "$1" ]] && echo "$1"
[[ -n "$2" ]] && exit $2 || exit 1
}
[[ -n "$tag" ]] || die "Need a tag argument. Use $0 --help for details"
Cela suppose bash ou Korn Shell, mais peut être converti en Bourne Shell classique en remplaçant [[]]
par []
.
Le test suivant vérifie qu’une variable est Null ou qu’une valeur lui est affectée. Les guillemets doubles sont très importants et doivent être utilisés!
VAL= # Creates a NULL variable
if [[ -z "$VAL" && "$VAL" = ’’ ]]
then
echo "The VAL variable is NULL"
fi
or
VAL=25
if [[ ! -z "$VAL" && "$VAL" != ’’ ]]
then
echo "The VAL variable is NOT NULL"
fi
Utilisez la correspondance de modèle pour détecter si la valeur consiste uniquement en des espaces:
pattern=$'*( |\t)'
if [[ $1 = $pattern ]]; then
echo "First parameter has no non-whitespace characters"
exit 1
fi
La citation $'...'
facilite l'ajout d'un onglet à la chaîne. Le modèle étendu *(...)
correspond à 0 ou plus des modèles entre parenthèses (similaire à regex ( |\t)*
). Le modèle est affecté à une variable car =
effectue la correspondance exacte des chaînes si une partie de son opérande de droite est entre guillemets. Nous effectuons donc les guillemets à l'avance pour faciliter la définition de la valeur.