Экспортируйте огибающую переменную, чтобы быть доступными во всех оболочках sub и возможными быть измененными?

Обновление ответа Жабр, чтобы также удалить возвраты каретки и сделать стирание клавиши Backspace предыдущих символов, которые были оба важны для меня для машинописного текста, сгенерированного на Cygwin:

#!/usr/bin/perl
while (<>) {
    s/ \e[ #%()*+\-.\/]. |
       \r | # Remove extra carriage returns also
       (?:\e\[|\x9b) [ -?]* [@-~] | # CSI ... Cmd
       (?:\e\]|\x9d) .*? (?:\e\\|[\a\x9c]) | # OSC ... (ST|BEL)
       (?:\e[P^_]|[\x90\x9e\x9f]) .*? (?:\e\\|\x9c) | # (DCS|PM|APC) ... ST
       \e.|[\x80-\x9f] //xg;
       1 while s/[^\b][\b]//g;  # remove all non-backspace followed by backspace
    print;
}
22
28.02.2011, 20:31
5 ответов

Копия среды распространяет к подоболочкам, таким образом, это работает:

$ export MY_VAR=200
$ bash
$ echo $MY_VAR
200

но так как это - копия, Вы не можете получить то значение до родительской оболочки — не путем изменения среды, по крайней мере.

Это кажется, что Вы на самом деле хотите пойти шаг вперед, который должен сделать что-то, что действует как глобальная переменная, совместно использованная "одноуровневыми" оболочками, инициируемыми отдельно от родителя — как Ваша новая вкладка в Терминале Gnome.

Главным образом ответ, "Вы не можете, потому что переменные среды не прокладывают себе путь". Однако существует другой ответ, который является, ну, в общем, можно всегда изрубить что-то. Один подход должен был бы записать значение переменной в файл, как ~/.myvar, и затем включайте это в ~/.bashrc. Затем каждая новая оболочка запустится со значения, считанного из того файла.

Вы могли пойти, шаг вперед — делает ~/.myvar будьте в формате MYVAR=200, и затем набор PROMPT_COMMAND=source ~/.myvar, который заставил бы значение быть перечитанным каждый раз, когда Вы получаете новую подсказку. Это все еще не вполне общая глобальная переменная, но это начинает действовать как он. Это не активируется, пока подсказка не возвращается, тем не менее, который в зависимости от то, что Вы пытаетесь сделать, могло быть серьезным ограничением.

И затем, конечно, следующая вещь состоит в том, чтобы автоматически записать изменения в ~/.myvar. Это становится немного более сложным, и я собираюсь остановиться в этой точке, потому что действительно, переменные среды не были предназначены, чтобы быть механизмом связи межоболочки, и лучше просто найти другой способ сделать это.

23
27.01.2020, 19:42
  • 1
    , я могу услышать, что оболочка визжит под пыткой –   28.02.2011, 20:58
  • 2
    Да извините. Вот почему я остановился. :) –  mattdm 28.02.2011, 21:08
  • 3
    , "который должен сделать что-то, что действует как глобальная переменная" - ну, действительно, это - то, что я пытался выполнить. ~/.myvar не симпатичен, но он работает. У Вас есть другое предложение? –  Somebody still uses you MS-DOS 28.02.2011, 21:11
  • 4
    Ну, давайте отступим немного. Почему Вы хотите глобальную переменную? –  mattdm 28.02.2011, 21:12
  • 5
    @mattdm: у Меня есть некоторая "бюрократия", которой я должен повиноваться. Один из них является набором кодов, которые я должен фиксировать наряду с комментарием. Эти коды находятся, теперь, в иерархии папок (home/user/projects/projectcode/code1/code2). Я сделал функцию, которая извлекает code1 и code2 в огибающий Вар (поэтому, когда я должен сделать действие, я просто вызываю функцию в dir с кодами), и их, при фиксировании, я использую энергию и существуют некоторые функции, которые читают их Вар и вставляют комментарий автоматически. Я думаю с помощью файлов для этого, может быть решение. –  Somebody still uses you MS-DOS 28.02.2011, 22:24

Предположим, что я имею export MY_VAR=0 в ~/.bashrc.

Это - Ваша ошибка тут же. Необходимо определить переменные среды в ~/.profile, который читается, когда Вы входите в систему. ~/.bashrc читается каждый раз, когда Вы запускаете оболочку; при запуске внутренней оболочки она переопределяет MY_VAR. Если бы Вы не сделали этого, Ваша переменная среды распространила бы вниз.

Для получения дополнительной информации о ~/.bashrc по сравнению с ~/.profile, посмотрите мой назад сообщения на это тема.

Обратите внимание, что восходящее распространение (получение измененного значения от подоболочки, автоматически отраженной в родительской оболочке), не является возможной, точкой.

13
27.01.2020, 19:42

Не используйте переменные среды вообще. Используйте файлы.

Чтобы препятствовать тому, чтобы процессы ступили друг на друга при обновлении/чтении файла, используйте lockfiles и маленький фронтенд updater сценарии, цель которых просто обновляет файл с 1$, если это не заблокировано. Lockfiles реализованы, в основном проверив, существует ли определенный файл (/var/run/yourscript.lck) и если он делает, ожидает файла, чтобы исчезнуть некоторое время, и перестать работать, если он не делает. Также необходимо удалить lockfile, сделано обновив файл.

Будьте готовы обработать ситуацию, где сценарий не может обновить файл, потому что файл занят.

3
27.01.2020, 19:42
  • 1
    прием: используйте каталоги вместо файлов для блокировки, потому что mkdir работы как атомарный тестировать-и-создавать. –  mattdm 28.02.2011, 22:53
  • 2
    Если Вы, парни хотят говорить о блокировке, то Вы могли бы также использовать flock(2) –  Ehtesh Choudhury 13.04.2013, 02:20
  • 3
    @mattdm я нашел что символьная ссылка ln -s dummy lockfile (даже если поврежденный), может работать также, поскольку это перестанет работать, если символьная ссылка уже существует. Интересно некоторый способ протестировать, если это на действительно 100% безопасно. –  Aquarius Power 18.08.2013, 23:26

Когда я просто погуглил этот вопрос, я пытался решить проблему обновления состояния (т.е. переменные оболочки) от из подоболочек. Так, чтобы можно было присвоить переменные, скажем, в конвейере – и присвоение будет прозрачно видимо к родителю.

От курса это не возможно простым способом, потому что отдельные части конвейера выполняются в подоболочках, которые являются fork'у редактора от родительской оболочки и поэтому есть память, которая является представлением копии на записи о памяти родителя. Однако я предположил, что тонкое и прозрачное решение могло быть возможным на основе вида "общей памяти" IPCs.

И я даже нашел реализацию точно этого дизайна..., но это находится в Perl.

Добавление этого ответа так или иначе как возможное решение.

1
27.01.2020, 19:42

Рыбная оболочка может сделать это с:

set -U MY_VAR 0

(см. http://fishsell.com/docs/current/Commands.html#sset )

для выполнения рыбной команды из другой оболочки Вы можете запустить Fish -c , Например, :

fish -c "set -u MY_VAR 0"
4
27.01.2020, 19:42

Теги

Похожие вопросы