Disons que j'ai exporté une variable:
foo=bar
export foo
Maintenant, je voudrais le désexporter. Cela veut dire que si je le fais, je ne sh -c 'echo "$foo"'
devrais pas y arriver bar
. foo
ne devrait pas apparaître du tout dans sh -c
l'environnement.
sh -c
n'est qu'un exemple, un moyen simple de montrer la présence d'une variable. La commande peut être n'importe quoi - elle peut être quelque chose dont le comportement est affecté simplement par la présence de la variable dans son environnement.
Je peux:
unset
la variable, et la perdre- Supprimez-le en utilisant
env
pour chaque commande:env -u foo sh -c 'echo "$foo"'
- peu pratique si vous souhaitez continuer à utiliser le shell actuel pendant un certain temps.
Idéalement, je voudrais conserver la valeur de la variable, mais ne pas la montrer du tout dans un processus enfant, pas même en tant que variable vide.
Je suppose que je pourrais faire:
otherfoo="$foo"; unset foo; foo="$otherfoo"; unset otherfoo
Cela risque de piétiner otherfoo
, s'il existe déjà.
Est-ce le seul moyen? Existe-t-il des moyens standard?
mktemp
si cela est suffisamment portable, annuler la valeur et source le fichier temporaire pour affecter la variable. Au moins un fichier temporaire peut être créé avec un nom plus ou moins arbitraire contrairement à une variable shell.sh -c
commande n'est qu'un exemple. Prenez n'importe quelle commande dans laquelle vous ne pouvez pas annuler une variable à sa place, si vous voulez.Réponses:
Il n'y a pas de moyen standard.
Vous pouvez éviter d'utiliser une variable temporaire en utilisant une fonction. La fonction suivante prend soin de garder les variables non définies non définies et les variables vides vides. Il ne prend cependant pas en charge les fonctionnalités trouvées dans certains shells telles que les variables en lecture seule ou typées.
Dans ksh, bash et zsh, vous pouvez annuler l'exportation d'une variable avec
typeset +x foo
. Cela préserve les propriétés spéciales telles que les types, il est donc préférable de l'utiliser. Je pense que tous les obus qui ont untypeset
intégré onttypeset +x
.la source
${var+foo}
, il évaluefoo
sivar
est défini, même s'il est vide, et rien d'autre.typeset +x
vsexport -n
pour les shells qui supportent les premiers? Est-ceexport -n
plus rare ou ne conserve-t-il pas certaines propriétés?export -n
outypeset +x
indifféremment. En ksh ou zsh, il n'y en a quetypeset +x
.EDIT: Pour
bash
seulement, comme indiqué dans les commentaires:L'
-n
option deexport
suppression de laexport
propriété de chaque nom donné. (Voirhelp export
.)Donc pour
bash
, la commande que vous voulez est:export -n foo
la source
J'ai écrit une fonction POSIX similaire, mais cela ne risque pas d'exécuter du code arbitraire:
Il traitera également autant d'arguments que vous voudrez le fournir. Si un argument est un nom valide qui n'est pas déjà défini autrement, il est ignoré en silence. Si un argument est un mauvais nom, il écrit dans stderr et s'arrête comme il convient, bien que tout nom valide précédant un invalide sur sa ligne de commande soit toujours traité.
J'ai pensé à une autre façon. Je l'aime beaucoup mieux.
Eh bien, les deux utilisent beaucoup des mêmes techniques. Fondamentalement, si une var shell n'est pas définie, une référence à celle-ci ne se développera pas avec une
+
expansion de paramètre. Mais s'il est défini - quelle que soit sa valeur - une expansion de paramètre comme:${parameter+word}
s'étendra àword
- et non à la valeur de la variable. Et donc les variables shell s'auto-testent et se remplacent elles-mêmes en cas de succès.Ils peuvent également échouer . Dans la fonction supérieure, si un mauvais nom est trouvé, je passe
$1
dans$2
et laisse$1
null parce que la prochaine chose que je fais est soit lereturn
succès si tous les arguments ont été traités et la boucle est terminée, soit, si l'argument n'était pas valide, le shell développez le$2
dans$1:?
lequel va tuer un shell scripté et retourner une interruption à un interactif lors de l'écritureword
sur stderr.Dans le second,
getopts
les affectations sont effectuées. Et il n'attribuera pas de mauvais nom - plutôt, il écrira un message d'erreur standard à stderr. De plus, il enregistre la valeur de l'argument$OPTARG
si l'argument était le nom d'une variable définie en premier lieu. Donc, après avoir faitgetopts
tout ce qui est nécessaire, il faut développereval
un ensembleOPTARG
dans l'affectation appropriée.la source
export
un nom étrange, cela ne tuera pas votre ordinateur.var=something; varname=var; export "$varname"
est parfaitement valide. il en va de même pourunset
et avec ceci et avec l'autre, mais à la minute où le contenu de cette"$varname"
variable devient fou, cela pourrait être regrettable. et c'est à peu près de cette façon que cettebash
débâcle d'exportation de fonctions s'est produite.