web-dev-qa-db-fra.com

Script shell - script de sortie si la variable est nulle ou vide

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?

12
Pinaki Mukherjee

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.)

23
tripleee

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 $#.

14
Micah Smith

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.
5
Pav K.

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
$
3
Arkadiusz Drabczyk

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 [].

1
Dan Christian

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
0
Pinaki Mukherjee

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.

0
chepner