как обмениваться переменными среды между оболочками, такими как глобальные переменные, связанные с мастером pid?

Таким образом, мне нужно обмениваться переменными среды между оболочками и что изменения в переменных должны быть быстро распознаны всеми оболочками, такими как глобальные переменные. Но они должны быть связаны с основным PID, поэтому я могу запустить 2 сценария оболочки, каждый из которых является мастером с тем же именем глобальной переменной, и он будет изменять только переменную, связанную с их основным PID.

Я использую bash для сценариев.

Мои текущие исследования таковы:

Модули
Я читал, что могу использовать проект модулей для этого: http://modules.sourceforge.net/ , но у меня есть огромные проблемы с попыткой сделать это, кажется, что нет примеров? также «модули» – слишком общее слово, очень сложно для Google, потому что смешивается со многими другими вещами … через несколько недель мои руки все еще пустые …

Простой текстовый файл
Я также читал, что я должен использовать простой текстовый файл для хранения / обновления / чтения переменных, как исходного файла сценария, с использованием flock чтобы избежать параллельной записи. Но есть проблемы, связанные с этим, например, одновременное изменение переменной одновременно двумя оболочками.

альтернативно
Я знаю, что после того, как «глобальная» переменная будет прочитана оболочкой, она сохранит это значение до тех пор, пока не будет сделано другое чтение; и другая оболочка может изменить ее в среднем, а также …
Может быть, очень быстрое внешнее приложение может обеспечить такое хранилище, и мы не будем пытаться использовать переменные окружения в качестве глобальных переменных? но я думаю, что любое SQL-решение будет слишком медленным …

7 Solutions collect form web for “как обмениваться переменными среды между оболочками, такими как глобальные переменные, связанные с мастером pid?”

Вы можете написать среду в файл с export -p и периодически просматривать его в других экземплярах . (команда включения). Но, как вы заметили, если есть параллельные модификации, результат будет невелик.

Если вы хотите, чтобы изменения распространялись мгновенно, вам придется использовать оболочку вокруг встроенного export которая также распространяет изменения на другие оболочки. В Linux вы можете использовать утилиту flock .

 global_export () { { flock 0 . /path/to/env [ $# -eq 0 ] || export "$@" export -p >/path/to/env } </path/to/env } 

Обратите внимание, что вам нужно будет вызывать global_export всякий раз, когда вы назначаете новое значение экспортируемой переменной.

Это довольно неуклюжий. Вероятно, есть лучший способ решить вашу проблему. Самый очевидный способ – использовать любую команду, используя эту переменную среды, вместо этого, вместо файлов конфигурации.

В дополнение к простому использованию flock от ответа Джайлса, я бы сделал что-то похожее на следующее:

Зарегистрируйте обработчик сигнала для перезагрузки файла:

 reload_env() { flock -s 3 . /path/to/env flock -u 3 } trap reload_env USR1 

Функция для записи файла и отправка SIGUSR1 во все оболочки, уведомляющие их о перезагрузке файла:

 export_env() { flock 3 export -p >/path/to/env flock -u 3 fuser -k -USR1 /path/to/env } 

Откройте файл, но ничего не сделайте с ним. Это просто так, что fuser сможет сигнализировать об этой оболочке:

 exec 3>>/path/to/env 

Порядок несколько важен. По крайней мере, часть exec ... должна быть после trap ... части. В противном случае мы могли бы открыть файл, а затем получить сигнал от вызова fuser прежде чем мы зарегистрируем наш обработчик сигнала.

ПРИМЕЧАНИЕ. Код полностью не проверен, но принцип стоит.
ПРИМЕЧАНИЕ 2. Этот примерный код предназначен для bash.

С оболочкой fish используйте универсальные переменные :

 set -U var value 

Конечно, это работает только через fish раковины, которыми управляет один и тот же пользователь.

Если вы хотите связать его с master pid , включите его в имя переменной

 set -U m${masterpid}var value 

Я хотел бы указать вам на названные каналы для этой цели. Вот один опрятный пример .

Именованные каналы создаются командой:

 mkfifo pipe_name 

Вы можете просто написать ему:

 echo "This text goes to the pipe" > pipe_name 

С другой стороны, вы можете читать из трубы как:

 read line < pipe_name; echo $line 

Вы можете создать несколько каналов на основе того, сколько оболочек вы хотите, чтобы они обменивались данными. Хорошие вещи о трубах – это не просто переменные. Фактически вы можете передавать любые данные между процессами. Вы можете передавать целые файлы, строки текстов, все, что пожелаете. Я считаю, что с учетом этого вы можете значительно упростить свои скрипты. Я могу себе представить, если ваши переменные указывают на местоположение данных или файл, а другой скрипт должен будет прочитать или получить его, вы можете напрямую передать данные / файл, даже не требуя переменную.

Если ksh93 является опцией, определенно есть способ реализовать то, что вы хотите, с функциями функции getter и setter, которые будут извлекать / сохранять значение переменной из / в общую память.

См. https://stackoverflow.com/questions/13726293/environment-variables-to-be-used-across-multiple-korn-ksh93-shell-scripts-get для получения более подробной информации.

В отличие от полезной функции универсальных переменных для fish , у вас есть доступ к реализации, поэтому вы можете ограничить совместное использование стоимости группой процессов, связанными с master pid через какой-либо механизм в вашем прецеденте, сохраняя при этом одно имя переменной.

Принимая во внимание ваши комментарии, вам нужен базовый IPC между сценариями оболочки. Я просто напишу в файлы (с переименованием для атомарности)

 varf=$(mktemp ./myvars.XXXXXX) echo myvar=newval > $varf mv -T -- $varf ./myvars 

И периодически читайте источники ./myvars.

IPC намного проще, например, с Python и модулем многопроцессорности.

Существует также этот проект ScriptEchoColor :

Он может автоматически создавать и управлять для вас текстовым файлом базы данных. На первом скрипте запуска будет создан BD-файл, другие скрипты будут символически привязываться к этому файлу в качестве собственной БД для управления значениями переменных, и поэтому оба могут обмениваться информацией.

Простой пример совместного использования этих файлов в папке примеров : secExplShareEnvVarsA.sh, secExplShareEnvVarsB.sh

И синхронизированный (безопасный и последовательный чтение / запись) общий доступ к БД там тоже: secExplSyncedShareEnvVarsA.sh, secExplSyncedShareEnvVarsB.sh

  • Установка XDG_DATA_HOME и XDG_CONFIG_HOME для компиляции / для каждой программы
  • пакетный инструмент для отправки файлов через webdav
  • Как «захватить» соответствующие файлы из файла поиска в bash?
  • «Stdin: не является tty» почтой для запуска скриптов в качестве заданий cron
  • Сравнить строки и обновить два разных файла
  • Выполните заданную команду на каждом подпути длинного пути
  • Команда Linux для переключения пользователя с паролем в качестве параметра
  • Скрипты на несколько серверов одновременно
  • Необходимо декодировать эту строку {$ HOSTNAME ^^} == {$ arrName ^^}
  • Bash Script - запуск удаленного X-перенаправленного приложения
  • Удаление файлов старше определенного файла
  • Interesting Posts

    Почему после перехода я могу синхронизировать работу, но не после cp -r *?

    Выйти в файл и прочитать его

    Сценарий оболочки для разблокировки гнома-ключа для школьного интернета при входе в систему

    Команда Wget, которая возвращает всех веб-страниц на веб-сервере

    Как я могу удалить все до шаблона и всего после другого шаблона из строки?

    Не удается создать en_US.UTF-8 Locale

    Любое приложение для воспроизведения песни при вставке гарнитуры

    Функция Bash не работает в Zsh

    Как создать правильный файл / etc / fstab для моего раздела LFS?

    Вопросительные знаки в именах файлов и Samba

    Получение сообщения «Ошибка при попытке открыть / dev / dvd исключительно» в конце процесса записи DVD при использовании growisofs

    Как лучше читать страницы руководства?

    Восстановить исходную конфигурацию fail2ban на CentOS 7

    Ограничить доступ пользователей в Linux

    Требуется уточнение apt_preferences

    Linux и Unix - лучшая ОС в мире.