Как получить PID подоболочки в Korn Shell (эквивалент $ BASHPID)

В bash у вас есть эта удобная переменная: $ BASHPID, которая всегда возвращает PID текущего запущенного подселлея. Как я могу получить PID подоболочки в ksh? Например, см. Код ниже:

#!/usr/bin/ksh93 echo "PID at start: $$" function run_in_background { echo "PID in run_in_background $$" run_something & echo "PID of backgrounded run_something: $!" } function run_something { echo "*** PID in run_something: $$" sleep 10; } run_in_background echo "PID of run in background $!" 

Это обеспечивает следующее:

 PID at start: 5328 PID in run_in_background 5328 *** PID in run_something: 5328 PID of backgrounded run_something: 5329 PID of run in background 5329 

То, что я хочу, это строка, начинающаяся с **** для вывода PID подоболочки, в примере, который будет 5329.

4 Solutions collect form web for “Как получить PID подоболочки в Korn Shell (эквивалент $ BASHPID)”

Я не думаю, что это доступно в ksh. Существует решение POSIX, которое включает в себя запуск внешнего процесса:

 sh -c 'echo $PPID' 

В Linux также работает readlink /proc/self , но я не вижу никакого преимущества (это может быть немного быстрее, оно может быть полезно в варианте BusyBox, который имеет readlink но не $PPID , но я не думаю, что есть один).

Обратите внимание, что для получения значения в оболочке вам нужно быть осторожным, чтобы не запускать эту команду в короткоживущей суб-оболочке. Например, p=$(sh -c 'echo $PPID') может отображать вывод подоболочки, который вызывает sh в sh команды (или это может быть не так, некоторые оболочки оптимизируют этот случай). Вместо этого запустите

 p=$(exec sh -c 'echo $PPID') 

Вы можете достичь того, чего хотите, но вам нужно поместить run_something в отдельный скрипт. Я не совсем уверен, почему, но $$ не переоценивается, когда он используется в функции в том же скрипте, который ее вызывает. Я предполагаю, что значение $$ присваивается один раз после того, как скрипт разбирается и до его выполнения.

run_in_background.sh

 # echo "PID at start: $$" function run_in_background { echo "PID in run_in_background $$" ./run_something.sh & echo "PID of backgrounded run_something: $!" } run_in_background echo "PID of run in background $!" 

run_something.sh

 # echo "*** PID in run_something: $$" sleep 10; 

вывод

 PID at start: 24395 PID in run_in_background 24395 PID of backgrounded run_something: 24396 PID of run in background 24396 *** PID in run_something: 24396 
 # KSH_VERSION hasn't always been a nameref, nor has it always existed. # Replace with a better test if needed. eg: # https://www.mirbsd.org/cvs.cgi/contrib/code/Snippets/getshver?rev=HEAD if [[ ${!KSH_VERSION} == .sh.version ]]; then # if AT&T ksh if builtin pids 2>/dev/null; then # >= ksh93 v- alpha function BASHPID.get { .sh.value=$(pids -f '%(pid)d'); } elif [[ -r /proc/self/stat ]]; then # Linux / some BSDs / maybe others function BASHPID.get { read -r .sh.value _ </proc/self/stat; } else # Crappy fallback function BASHPID.get { .sh.value=$(exec sh -c 'echo $PPID'); } fi elif [[ ! ${BASHPID+_} ]]; then echo 'BASHPID requires Bash, ksh93, or mksh >= R41' >&2 exit 1 fi 

После ответа @Gilles, с которым я столкнулся, в то время как решение другой проблемы, что у меня было, я бросил вместе быстрый тест программы, которая лежит в основе теории, что правильный ответ:

 MYPID=$(exec sh -c 'echo $PPID') 

Я обнаружил, что времена, когда exec не требуется, но я подтвердил, что использование этого метода – единственный способ получить правильный pid все время во всех оболочках, которые я пробовал. Вот мой тест:

 #!/bin/sh pids() { echo ------ pstree -pg $PPID echo 'PPID = ' $PPID echo '$$ = ' $$ echo 'BASHPID =' $BASHPID echo -n 'sh -c echo $PPID = '; sh -c 'echo $PPID' echo -n '$(sh -c '\''echo $PPID'\'') = '; echo $(sh -c 'echo $PPID') echo -n '$(exec sh -c '\''echo $PPID'\'') = '; echo $(exec sh -c 'echo $PPID') echo -n 'p=$(sh -c '\''echo $PPID'\'') = '; p=$(sh -c 'echo $PPID') ; echo $p echo -n 'p=$(exec sh -c '\''echo $PPID'\'') = '; p=$(exec sh -c 'echo $PPID') ; echo $p } pids pids | cat echo -e "$(pids)" 

и его выход

 ------ bash(5975,5975)---pidtest(13474,13474)---pstree(13475,13474) PPID = 5975 $$ = 13474 BASHPID = 13474 sh -c echo $PPID = 13474 $(sh -c 'echo $PPID') = 13474 $(exec sh -c 'echo $PPID') = 13474 p=$(sh -c 'echo $PPID') = 13474 p=$(exec sh -c 'echo $PPID') = 13474 ------ bash(5975,5975)---pidtest(13474,13474)-+-cat(13482,13474) `-pidtest(13481,13474)---pstree(13483,13474) PPID = 5975 $$ = 13474 BASHPID = 13481 sh -c echo $PPID = 13481 $(sh -c 'echo $PPID') = 13481 $(exec sh -c 'echo $PPID') = 13481 p=$(sh -c 'echo $PPID') = 13481 p=$(exec sh -c 'echo $PPID') = 13481 ------ bash(5975,5975)---pidtest(13474,13474)---pidtest(13489,13474)---pstree(13490,13474) PPID = 5975 $$ = 13474 BASHPID = 13489 sh -c echo $PPID = 13489 $(sh -c 'echo $PPID') = 13492 $(exec sh -c 'echo $PPID') = 13489 p=$(sh -c 'echo $PPID') = 13495 p=$(exec sh -c 'echo $PPID') = 13489 

Подставьте свою любимую оболочку в shebang: sh , bash , mksh , ksh и т. Д.

Я не понимаю, почему случаи 2 и 3 дают разные результаты, а также почему результаты для случая 3 отличаются друг от друга. Я пробовал bash , ksh и mksh на Arch Linux FWIW.

  • cd в скрипте bash без псевдонима, функция, источник
  • Буфер обмена VNC не работает
  • Как войти в удаленную учетную запись пользователя с помощью пароля и выполнить набор команд?
  • Экспортируйте vars env в окно tmux windows / сессии / панели
  • Есть ли простой тест на что-либо, напечатанное на stderr в shell / Bash?
  • Невозможно grep список заданий, когда задания, вызванные функцией
  • Строка состояния Tmux мигает командой из # () перед отображением результата
  • Использование подоболочки для передачи параметров с пробелами
  • Заполнение вкладки Bash происходит не в подстановке команд
  • фигурные скобки и подоболочка
  • Flock, похоже, не работает
  • Interesting Posts

    Написание TCP-сервера в bash

    Как проверить систему Fedora, если IPv6 отключен или нет?

    заменить строку в цикле

    Bash для получения разрешенного исполняемого пути?

    Проверка прав на файл профиля в домашнем каталоге: должно ли это быть сделано?

    Как мне отредактировать Vagrantfile, чтобы Vagrant знал, как получить файл .box с моего хоста?

    Как использовать файлы ПК MonoDevelop с условными именами условных обозначений UNIX?

    Как определяется определение типа файла по расширению имени файла в дополнение к спецификации XDG (mimeapps.list)

    Найдите PID верхнего использования CPU / MEM, сохраните переменную оболочки

    Как использовать инструмент diff, чтобы получить разницу между каталогами с библиотеками и источником?

    Почему медленнее время поиска кодов на одном компьютере по сравнению с другим в той же локальной сети?

    OpenWRT mount / boot ethernet HDD

    Как определить LVM-over-LUKS или LUKS-over-LVM

    Карта нестандартных скрытых отчетов для scancodes для игровой клавиатуры Logitech G105

    Экспорт из представления альбома digiKam в локальную файловую систему?

    Linux и Unix - лучшая ОС в мире.