如何在 Korn Shell 中获取子 shell 的 PID(相当于 $BASHPID)

如何在 Korn Shell 中获取子 shell 的 PID(相当于 $BASHPID)

在 bash 中,你有这个方便的变量:$BASHPID,它总是返回当前运行的子 shell 的 PID。如何在 ksh 中获取子 shell 的 PID?例如看下面的代码:

#!/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

我想要的是以 开头的行来****输出子 shell 的 PID,在示例中为 5329。

答案1

我不认为这在 ksh 中可用。有一个 POSIX 解决方案涉及运行外部进程:

sh -c 'echo $PPID'

在 Linux 上,readlink /proc/self也可以工作,但我看不到任何优势(它可能会稍微快一些;它可能在具有readlink但不具有 的BusyBox 变体上有用$PPID,但我认为没有)。

请注意,为了获取 shell 中的值,您需要注意不要在短期子 shell 中运行该命令。例如,可能会显示在命令替换中p=$(sh -c 'echo $PPID')调用的子 shell 的输出(也可能不会,某些 shell 会优化这种情况)。sh相反,运行

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

答案2

您可以实现您想要的,但是您需要将 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

答案3

# KSH_VERSION hasn't always been a nameref, nor has it always existed.
# Replace with a better test if needed. e.g.:
# 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

答案4

#!/bin/ksh
 function os_python_pid {
/usr/bin/python  -c 'import os,sys ; sys.stdout.write(str(os.getppid()))'
}
function os_perl_pid {
/usr/bin/perl -e 'print getppid'
}

echo "I am $$"
    echo "I am $(os_python_pid) :: $(os_perl_pid)"
function proce {
  sleep 3
  echo "$1 :: $(os_python_pid) :: $(os_perl_pid)"
}

for x in aa bb cc; do
  proce $x &
  echo "Started: $!"
done

相关内容