Как я могу получить pid subshell?
Например:
$ echo $$
16808
Это не работает, потому что оригинальная оболочка расширяется $$
:
$ ( echo $$ )
16808
Почему одинарные кавычки не работают? После того, как исходная оболочка удаляет одинарную кавычку, не расширяется ли подоболочка $$
?
$ ( echo '$$' )
$$
Почему тоже eval
не работает? Является ли в eval
ведении субоболочке? Почему это дает мне оригинальный PID оболочки?
$ ( eval echo '$$' )
16808
Спасибо.
$$
расширения» против «другой pid в подоболочке»).Ответы:
В дополнение к
bash
s$BASHPID
вы можете сделать это с помощью:Пример:
Вы можете превратить это в функцию:
Обратите внимание, что некоторые оболочки (например,
zsh
илиksh93
) НЕ запускают подпроцесс для каждой подоболочки, созданной с помощью(...)
; в этом случае$pid
может оказаться так же, как$$
и это правильно, потому что это PID процесса, из которогоgetpid
был вызван.источник
ksh93
, например, это не так.(...)
из примера, который не может порождать отдельный процесс, как это происходит вbash
.zsh
илиyash
оптимизируютfork()
последнюю команду в подоболочке. Они могут даже оптимизировать ответвление для подоболочки, если это последняя команда в сценарии, чтобы выgetpid
могли даже сообщить о родительском объекте$$
. Вы можете определитьgetpid
как:getpid(){ sh -c 'echo "$PPID"'; return; }
отключить, чтобы избежать проблемы.exec
или без этой оптимизацииsh -c ...
процесс будет внуком, а не дочерним по отношению к процессу, в котором используется$(...)
подстановка команд, и$PPID
будет pid$(...)
подоболочки. Это именно то, что происходит в примереset -E
+trap ERR
bash выше.test "$1"
проверяет,$1
является ли пустая строка или нет - быстрый и грязный способ проверить, была ли эта функция получилаvarname
аргумент для присвоения pid или нет; использование функции не было самой яркой идеей на первом месте.Из руководства:
Связанные с:
источник
$$
в подоболочках.$BASHPID
переменную и использовать ее в подоболочке. Есть$PPID
, но это родительский PID оболочки в том же смысле, что$$
и PID оболочки (он не сбрасывается в подоболочке). Там нет$BASHPPID
переменной.