Une copie de l'environnement se propage aux sous-shells, donc cela fonctionne:
$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200
mais comme il s'agit d'une copie, vous ne pouvez pas obtenir cette valeur jusqu'au shell parent - pas en changeant l'environnement, au moins.
Il semble que vous vouliez réellement aller plus loin, c'est-à-dire créer quelque chose qui agit comme une variable globale, partagée par des shells "frères" initiés séparément du parent - comme votre nouvel onglet dans Gnome Terminal.
Généralement, la réponse est "vous ne pouvez pas, car les variables d'environnement ne fonctionnent pas de cette façon". Cependant, il y a une autre réponse, qui est, eh bien, vous pouvez toujours pirater quelque chose. Une approche consisterait à écrire la valeur de la variable dans un fichier, comme ~/.myvar
, puis à l'inclure dans ~/.bashrc
. Ensuite, chaque nouveau shell commencera avec la valeur lue dans ce fichier.
Vous pourriez aller plus loin - faites ~/.myvar
être au format MYVAR=200
, puis définissez PROMPT_COMMAND=source ~/.myvar
, ce qui entraînerait la relecture de la valeur chaque fois que vous obtenez une nouvelle invite. Ce n'est pas encore tout à fait une variable globale partagée, mais ça commence à agir comme ça. Il ne s'activera pas jusqu'à ce qu'une invite revienne, ce qui, selon ce que vous essayez de faire, pourrait être une sérieuse limitation.
Et puis, bien sûr, la prochaine chose est d' écrire automatiquement les modifications ~/.myvar
. Cela devient un peu plus compliqué, et je vais m'arrêter ici, car vraiment, les variables d'environnement n'étaient pas censées être un mécanisme de communication inter-shell, et il vaut mieux trouver simplement une autre façon de le faire.
Voilà votre erreur. Vous devez définir vos variables d'environnement dans
~/.profile
, qui sont lues lorsque vous vous connectez.~/.bashrc
Est lu chaque fois que vous démarrez un shell; lorsque vous démarrez le shell interne, il remplaceMY_VAR
. Si vous ne l'aviez pas fait, votre variable d'environnement se propagerait vers le bas.Pour plus d'informations sur
~/.bashrc
vs~/.profile
, consultez mes précédents articles sur ce sujet .Notez que la propagation vers le haut (obtenir une valeur modifiée du sous-shell automatiquement reflété dans le shell parent) n'est pas possible, point final.
la source
La coquille de poisson peut le faire avec:
(voir http://fishshell.com/docs/current/commands.html#set )
Pour exécuter une commande fish à partir d'un autre shell, vous pouvez exécuter
fish -c
, par exemple:la source
N'utilisez pas du tout de variables d'environnement. Utilisez des fichiers.
Pour empêcher les processus de marcher les uns sur les autres lors de la mise à jour / lecture du fichier, utilisez des fichiers de verrouillage et de petits scripts de mise à jour frontaux dont le but est simplement de mettre à jour un fichier avec $ 1 s'il n'est pas verrouillé. Les fichiers de verrouillage sont implémentés en vérifiant essentiellement si un fichier spécifique existe (/var/run/yourscript.lck) et si c'est le cas, attendez que le fichier disparaisse pendant un certain temps et échouez s'il ne le fait pas. Vous devez également supprimer le fichier de verrouillage une fois la mise à jour du fichier terminée.
Soyez prêt à gérer une situation où un script ne peut pas mettre à jour un fichier car le fichier est occupé.
la source
mkdir
fonctionne comme un test et création atomique.flock(2)
ln -s dummy lockfile
(même s'il était cassé) peut également fonctionner car il échouera si le lien symbolique existe déjà. Je me demande un moyen de tester si c'est vraiment 100% sécurisé.Quand je viens de googler cette question, j'essayais de résoudre le problème de la mise à jour de l'état (c'est-à-dire des variables de shell) à partir de sous-coquilles. Pour que l'on puisse affecter des variables, disons, à l'intérieur d'un pipeline - et l'affectation serait visible de manière transparente pour le parent.
Bien sûr, cela n'est pas possible d'une manière simple car les parties individuelles d'un pipeline sont exécutées dans des sous-
fork
coquilles , qui sont éditées à partir du shell parent et ont donc une mémoire qui est une vue de copie sur écriture dans la mémoire du parent. Cependant, je supposais qu'une solution mince et transparente pourrait être possible en se basant sur des IPC de type " mémoire partagée " .Et j'ai même trouvé une implémentation de cette conception exactement ... mais c'est en Perl.
Ajouter cette réponse de toute façon comme solution possible.
la source