捕获函数内调用该函数的进程的 id

捕获函数内调用该函数的进程的 id

我想记录在 Korn shell 脚本中调用特定函数的进程的 ID。

例如,让我们考虑一个用户定义的自动加载函数 SQUARE。现在,如果 TestSquare.sh 脚本调用 SQUARE 函数。我想捕获正在执行的 TestSquare.sh 的进程 ID 以及 TestSquare.sh 进程的启动时间。

我不想将任何参数传递给函数。我想仅使用调用脚本的进程 ID 来构造所有信息。

答案1

shell 的进程 ID 在特殊参数中可用$$(在 ksh 手册中,这记录在“参数扩展”部分下)。

log () {
  printf "script=%s pid=%d message=%s\n" "$0" "$$" "$1"
}

请注意,这$$是脚本的进程 ID。如果您在子 shell 中执行代码(即在括号中、在命令替换内、在管道的左侧等),则不会更改 的值$$。如果您想要实际发出日志消息的进程 ID,可以通过调用子进程并告诉它报告其父进程 ID 来获取它。 (有些 shell 有一个变量,但我认为不是 ATT ksh。)

log () {
  printf "script=%s script_pid=%d emitting_pid=%d message=%s\n" \
         "$0" "$$" "$(sh -c 'echo $PPID')" "$1"
}

如果要记录脚本的开始时间,最简单的方法是在脚本启动时将当前时间分配给变量。

#!/bin/ksh
start_time=$(date)

如果您稍后需要获取脚本的开始时间,可以使用 获取ps -o stime,但这不会为您提供完整的日期和时间。或者,您可以根据变量SECONDS(始终包含自脚本启动以来的秒数)和当前日期进行计算。如果您使用 ksh,您可能没有 GNU date,这使您没有方便的日期计算工具。 awk 提供了一种迂回方式来获取自时代,因此以下代码片段设置start_time脚本自纪元以来的开始时间(以秒为单位):

start_time=$(export SECONDS; awk 'BEGIN {srand(); print srand() - ENVIRON["SECONDS"]; exit}')

相关内容