Когда вы запускаете скрипт, он получает свою оболочку и свое окружение, которые исчезают снова, как только скрипт завершает работу. Чтобы сохранить переменные окружения вокруг, отправьте скрипт в вашу текущую оболочку:
$ source ./a.sh
или эквивалентно (но немного более порционно), используя команду POSIX dot:
$ . ./a.sh
Затем определения будут помещены в ваше текущее окружение оболочки и унаследованы любыми программами, которые вы запустите из неё.
Чтобы быть ближе к выполнению скрипта, . a.sh
найдет a.sh путем поиска по каталогам в переменной окружения PATH
.
Есть некоторые тонкости в том, как они ведут себя и являются ли .
и источником
одинаковыми (или присутствуют вообще). . ./a.sh
определенно будут вести себя одинаково во всех POSIX-совместимых оболочках, но источник
и .
, и . a.sh
и . ./a.sh
, могут отличаться. Для Bash source
и .
во всех случаях одинаковы ; для zsh source
всегда сначала проверяет текущий каталог ; ksh по сути похож.
Если имя скрипта задано в виде пути (содержащего /
), то этот путь используется непосредственно во всех случаях. Наиболее надежным является . ./script
или . /path/to/script
.
Многие оболочки оптимизируют последнюю команду в сценарии, выполняя команду в одном процессе:
$ sh -c 'ps
ps'
PID TTY TIME CMD
32673 pts/3 00:00:00 zsh
32696 pts/3 00:00:00 sh
32697 pts/3 00:00:00 ps
PID TTY TIME CMD
32673 pts/3 00:00:00 zsh
32696 pts/3 00:00:00 ps
Посмотрите, как второй ps
был выполнен в процессе, который первоначально выполнял sh
(32696), а затем его родителем является родительский элемент sh
(в моем случае здесь zsh
моя интерактивная оболочка).
Этого можно избежать, добавив строку exit
:
#! /bin/sh -
foo
exit
sh
не может выполнить foo
в том же процессе, потому что ему еще нужно интерпретировать после ] foo
закончил. Поэтому вместо этого он будет запускать foo
в другом процессе и ждать его. Затем запустите exit
(что приведет к выходу из сценария с тем же статусом выхода, что и для foo
).
Это не очень оптимально, так как вы могли бы сохранить здесь процесс.
Лучший способ сообщить foo
путь к foocaller
):
#! /bin/sh -
CALLER=$0 foo
Тогда foo
может запросить Переменная среды CALLER
для получения пути к вызывающей стороне ( import os; print (os.environ ["CALLER"])
в python)