Получение родительского пути из сценария

Когда вы запускаете скрипт, он получает свою оболочку и свое окружение, которые исчезают снова, как только скрипт завершает работу. Чтобы сохранить переменные окружения вокруг, отправьте скрипт в вашу текущую оболочку:

$ 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.

1
23.05.2017, 14:33
1 ответ

Многие оболочки оптимизируют последнюю команду в сценарии, выполняя команду в одном процессе:

$ 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)

3
27.01.2020, 23:28

Теги

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