Я знаю, что могу считать информацию родителя в дочернем процессе путем экспорта переменной
myVariable=1
bash
echo $myVariable
exit
export myVariable=1
bash
echo $myVariable # 1
Как я могу получить доступ к переменным, определенным в дочернем процессе от родителя?
bash
a=2
suspend
echo $a
Вы не можете сделать этого.
При запуске новой оболочки это - несвязанный процесс, и родитель не может "посмотреть в" нем для наблюдения то, что это имеет в памяти (это - своего рода граница безопасности). Его переменные не совместно используются и не публикуются, где кто-то еще видит их.
Это получает копию существующих переменных среды, но любые изменения, которые это вносит в них, для себя одни, и ее дети. Существует не "назад" коммуникация до выходов оболочки и всех, что там в той точке, единственный код выхода.
Когда Вы делаете это в интерактивном режиме, поскольку Вы показали, это - конец истории. Ваш лучший выбор состоит в том, чтобы сохранить данные в файл, который можно затем считать из или source
въезжайте задним ходом к родителю. Если Вы действительно не можете использовать файл, у меня есть ужасный способ сделать его правильно в конце, но я рекомендую заново продумать то, чего Вы пытаетесь достигнуть - было бы хорошо смочь сделать эту работу обычно (и некоторые другие оболочки действительно имеют совместно используемые переменные!), это просто не достижимо здесь.
Если Вы делаете программу или сценарий оболочки, который работает нев интерактивном режиме, некоторые или весь из source
, eval
, и распечатывание данных к стандартному выводу может помочь Вам, как отмечено в существующем ответе. При выходе из дочерней оболочки можно пасовать назад единственный байт информации в коде выхода с exit 123
, с которым можно читать $?
в родителе.
Если действительно действительно необходимо переместить что-то, вот очень противный взлом для достижения его в интерактивном режиме без промежуточных файлов:
$ bash
$ export a=2
$ sleep 60 & echo $!
2198
$ suspend
$ xargs -0 < /proc/2198/environ printf '%s\n' | grep '^a='
a=2
$ a=$(xargs -0 < /proc/2198/environ printf '%s\n' | grep '^a=' | cut -d= -f2-)
$ echo $a
2
$ [1]+ Done sleep 60
Существуют значительные ограничения здесь, особенно если Вы не контролируете целую среду - новая строка в значении переменной среды могла бы обмануть Вас в устанавливание значения, которое Вы не хотели, например.
Это работает путем экспорта a
так, чтобы это появилось в среде подпроцессов и затем запуска одного (sleep 60
здесь), в фоновом режиме (&
), с PID sleep
распечатанный (echo $!
). При приостановке внутренней оболочки можно читать sleep
переменные среды процесса, данные его родителем с внешней стороны - это общедоступно в /proc
файловая система - но они разделяются пустыми байтами, таким образом, xargs -0
разделяет их и printf '%s\n'
производит тот на строку. В той точке существует полный список переменных, и мы можем grep
тот мы хотим, дополнительно прерывая просто значение после =
с cut
и установка его. sleep
закончится самостоятельно, который является тем, что мы видим в конце расшифровки стенограммы ([1]+ Done ...
).
Необходимо было бы сделать все это снова, если бы Вы хотели взять на изменении в a
в ребенке - и ребенке никогда не будет видеть изменения, в которое Вы вносите a
в родителе: все, что мы сделали, делают другую копию. Причина sleep
процесс состоит в том, что мы можем только видеть входящие переменные среды процесса и не любое из значений внутренней переменной оболочки, даже если они экспортируются.
Я не рекомендую делать это или полагаться на него, и я не вижу значения в использовании его, но если Вы действительно заканчиваете в ситуации, где это действительно, жизненно необходимо затем, что это должно работать.
От этого вопроса на Переполнении стека решение состоит в том, чтобы использовать source
при выполнении дочернего процесса:
В a.sh
сделать source b.sh
вместо ./b.sh
a.sh
должен быть похожим на это:
#!/bin/bash
export A=1
source b.sh
echo parent "$A"