Есть ли в * nix мире способ для сценария оболочки иметь информацию о том, какая программа его выполнила?
Пример:
/path/to/script1 /path/to/script_xyz
в этом воображаемом сценарии script_xyz
будет иметь информацию о пути ( /path/to/script1
)
или
PID процесса
субъекта, который его выполнил.
Примечание: мне любопытно узнать о различных решениях и подходах, я не ожидаю, что это действительно возможно
shell-script
shell
process
debugging
Милош Чаконович
источник
источник
Ответы:
Часто возникает путаница между процессом разветвления и выполнением.
Когда вы делаете по приглашению
bash
оболочки.Процесс P1, выдающий это
$
приглашение, в настоящий момент выполняетbash
код. Этотbash
код разветвляет новый процесс P2, который выполняется,/bin/sh
который затем выполняется/usr/bin/env
, который затем выполняется/bin/ps
.Таким образом , P2 , в свою очередь выполняется код
bash
,sh
,env
иps
.ps
(или любая другая команда, такая как скрипт, который мы использовали бы здесь) не может знать, что она была выполненаenv
командой.Все это можно сделать , это выяснить , что его родительский процесс идентификатор, который в этом случае будет либо P1 или
1
если P1 умер в промежутке или на Linux другого процесса , который был назначен в качестве subreaper вместо1
.Затем он может запросить у системы, какая команда выполняется в данный момент (например,
readlink /proc/<pid>/exe
в Linux) или какие аргументы были переданы последней команде, которую он выполнил (например, вps -o args= -p <pid>
).Если вы хотите, чтобы ваш сценарий знал, что его вызвало, надежным способом было бы, чтобы вызывающий сообщал об этом. Это может быть сделано, например, через переменную окружения. Например,
script1
может быть написано как:И
script2
:$INVOKER
будет ( обычно ) содержать путь кscript1
. В некоторых случаях это может быть относительный путь, и путь будет относительно текущего рабочего каталога на моментscript1
запуска. Так что, еслиscript1
изменит текущий рабочий каталог перед вызовомscript2
,script2
получит неверную информацию относительно того, что вызвало его. Поэтому может быть предпочтительнее убедиться, что он$INVOKER
содержит абсолютный путь (предпочтительно с сохранением базового имени), например, записав вscript1
виде:В оболочках POSIX
$PPID
будет содержаться pid родительского процесса, который выполнил оболочку во время инициализации этой оболочки. После этого, как видно выше, родительский процесс может измениться, если процесс id$PPID
умирает.zsh
вzsh/system
модуле, может запросить текущий родительский pid текущей (под) оболочки с помощью$sysparams[ppid]
. В оболочках POSIX вы можете получить текущий ppid процесса, который выполнил интерпретатор (при условии, что он все еще выполняется)ps -o ppid= -p "$$"
. С помощьюbash
вы можете получить ppid текущей (под) оболочки с помощьюps -o ppid= -p "$BASHPID"
.источник
Да, программа может знать, кто ее родитель.
Для иллюстрации давайте создадим два сценария bash. Первый сообщает свой PID и запускает второй скрипт:
Второй скрипт сообщает свой идентификатор процесса, PID своего родителя и командную строку, используемую для запуска родителя:
Теперь давайте запустим это:
Как вы можете видеть, второй скрипт действительно знает PID своего родителя. Используя
ps
, этот PID показывает командную строку, используемую для вызова родителя.Более подробное обсуждение PPID см. В ответе Стефана Шазеласа .
источник
s1
,s2
иPPID
значения, но потом, в несколько строк послеERROR: Unsupported SysV option.
и в несколько строк с дополнительным объяснением и - пустое значение дляParent command
ps
изprocps-ng
пакета, версия 3.3.12. Как предположил Jasen, вы, вероятно, используете другую версию, для которой может потребоваться другой синтаксис для печати командной строки родителя. Попробуйps -f | grep $PPID
.