Expansion des paramètres
La réponse évidente est d'utiliser l'une des formes spéciales d'expansion des paramètres:
: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}
Ou mieux (voir la section «Position des guillemets doubles» ci-dessous):
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
La première variante (en utilisant simplement ?
) nécessite que STATE soit défini, mais STATE = "" (une chaîne vide) est OK - pas exactement ce que vous voulez, mais la notation alternative et plus ancienne.
La deuxième variante (en utilisant :?
) nécessite que DEST soit défini et non vide.
Si vous ne fournissez aucun message, le shell fournit un message par défaut.
La ${var?}
construction est portable vers la version 7 UNIX et le Bourne Shell (1978 ou environ). La ${var:?}
construction est un peu plus récente: je pense que c'était dans System III UNIX vers 1981, mais peut-être dans PWB UNIX avant cela. Il se trouve donc dans le Korn Shell, et dans les shells POSIX, notamment spécifiquement Bash.
Il est généralement documenté dans la page de manuel du shell dans une section appelée Expansion des paramètres . Par exemple, le bash
manuel dit:
${parameter:?word}
Erreur d'affichage si Null ou Unset. Si le paramètre est nul ou non défini, l'expansion de word (ou d'un message à cet effet si ce mot n'est pas présent) est écrite dans l'erreur standard et le shell, s'il n'est pas interactif, se ferme. Sinon, la valeur du paramètre est substituée.
Le Colon Command
Je devrais probablement ajouter que la commande colon a simplement ses arguments évalués puis réussit. C'est la notation originale du commentaire du shell (avant ' #
' jusqu'à la fin de la ligne). Pendant longtemps, les scripts shell Bourne ont eu deux points comme premier caractère. Le C Shell lirait un script et utiliserait le premier caractère pour déterminer s'il s'agissait du C Shell (un ' #
' hachage) ou du Bourne shell (un ' :
' deux-points). Ensuite, le noyau est intervenu et a ajouté un support pour les commentaires ' #!/path/to/program
' et le shell Bourne ' #
', et la convention du côlon a été abandonnée. Mais si vous tombez sur un script qui commence par deux points, vous saurez maintenant pourquoi.
Position des guillemets doubles
Blong a demandé dans un commentaire :
Des réflexions sur cette discussion? https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749
L'essentiel de la discussion est:
… Cependant, quand je shellcheck
le fais (avec la version 0.4.1), je reçois ce message:
In script.sh line 13:
: ${FOO:?"The environment variable 'FOO' must be set and non-empty"}
^-- SC2086: Double quote to prevent globbing and word splitting.
Un conseil sur ce que je dois faire dans ce cas?
La réponse courte est "faites comme shellcheck
suggéré":
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Pour illustrer pourquoi, étudiez ce qui suit. Notez que la :
commande ne fait pas écho à ses arguments (mais le shell évalue les arguments). Nous voulons voir les arguments, donc le code ci-dessous utilise printf "%s\n"
à la place de :
.
$ mkdir junk
$ cd junk
$ > abc
$ > def
$ > ghi
$
$ x="*"
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
abc
def
ghi
$ unset x
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
bash: x: You must set x
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
bash: x: You must set x
$ x="*"
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
*
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
abc
def
ghi
$ x=
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$ unset x
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$
Notez comment la valeur de $x
est développée en premier *
, puis une liste de noms de fichiers lorsque l'expression globale n'est pas entre guillemets. C'est ce qui shellcheck
recommande devrait être corrigé. Je n'ai pas vérifié qu'il ne s'oppose pas au formulaire où l'expression est placée entre guillemets, mais c'est une supposition raisonnable que ce serait OK.