Disons que j'ai un script en train de faire:
some-command "$var1" "$var2" ...
Et, dans le cas qui var1
est vide, je préfère qu'il soit remplacé par rien au lieu de la chaîne vide, de sorte que la commande exécutée soit:
some-command "$var2" ...
et pas:
some-command '' "$var2" ...
Existe-t-il un moyen plus simple que de tester la variable et de l'inclure conditionnellement?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
Y a-t-il une substitution de paramètres qui peut s'étendre à rien en bash, zsh ou similaire? Je pourrais toujours vouloir utiliser la globalisation dans le reste des arguments, donc désactiver cela et ne pas citer la variable n'est pas une option.
bash
shell-script
zsh
variable
muru
la source
la source
man
page? (-;Réponses:
Les coques et Bash conformes à Posix ont
${parameter:+word}
:Vous pouvez donc simplement faire:
et doivent
var1
être vérifiées et"$var1"
utilisées si elles sont définies et non vides (avec les règles ordinaires de guillemet double). Sinon, il se développe à rien. Notez que seule la partie intérieure est citée ici, pas le tout.La même chose fonctionne également dans zsh. Vous devez répéter la variable, donc ce n'est pas idéal, mais cela fonctionne exactement comme vous le vouliez.
Si vous souhaitez qu'une variable définie mais vide se développe en un argument vide, utilisez
${var1+"$var1"}
plutôt.la source
word
partie l'est.:+
et+
.sh
/dash
pour des scripts de chokepoint potentiels, donc j'apprécie toujours quand quelqu'un montre comment une chose est possible sans recourir à Bash.C'est ce que
zsh
fait par défaut lorsque vous omettez les guillemets:En fait, la seule raison pour laquelle vous avez toujours besoin de guillemets en zsh autour de l'expansion des paramètres est d'éviter ce comportement (la suppression vide) car il
zsh
n'a pas les autres problèmes qui affectent les autres shells lorsque vous ne citez pas les extensions de paramètres (la séparation implicite + glob) .Vous pouvez faire de même avec d'autres shells de type POSIX si vous désactivez le split et le glob:
Maintenant, je dirais que si votre variable peut avoir une valeur de 0 ou 1, ce devrait être un tableau et non une variable scalaire et utiliser:
Et utilisez
var1=(value)
quandvar1
doit contenir une valeur,var1=('')
quand il doit contenir une valeur vide etvar1=()
quand il ne doit contenir aucune valeur.la source
J'ai rencontré cela en utilisant rsync dans un script bash qui a démarré la commande avec ou sans
-n
basculer les exécutions à sec. Il s'avère que rsync et un certain nombre de commandes gnu prennent''
comme premier argument valide et agissent différemment que s'il n'y était pas.Cela a pris un certain temps à déboguer car les paramètres nuls sont presque complètement invisibles.
Quelqu'un sur la liste rsync m'a montré un moyen d'éviter ce problème tout en simplifiant grandement mon codage. Si je comprends bien, c'est une variation de la dernière suggestion de @ Stéphane Chazelas.
Créez vos arguments de commande dans un certain nombre de variables distinctes. Ceux-ci peuvent être définis dans n'importe quel ordre ou logique qui convient au problème.
Ensuite, à la fin, utilisez les variables pour construire un tableau avec tout à sa place et utilisez-le comme arguments de la commande réelle.
De cette façon, la commande n'est émise qu'à un seul endroit dans le code au lieu d'être répétée pour chaque variation des arguments.
Toute variable vide disparaît simplement à l'aide de cette méthode.
Je sais que l'utilisation d'eval est très mal vue. Je ne me souviens pas de tous les détails, mais il me semblait en avoir besoin pour que les choses fonctionnent de cette façon - quelque chose à voir avec la gestion des paramètres avec un espace blanc intégré.
Exemple:
la source