在子进程启动之前或完成之后发现其 PID

在子进程启动之前或完成之后发现其 PID

我写了一个 shell 脚本来启动一个程序${programName}

该程序恰好在文件夹 中创建临时工作文件,<workFolderLocation>/SAS_work<randomHex>00<pidHex>_<server>其中是该程序pidHex的十六进制表示形式。PID通常,当程序完成时,这个临时文件夹就会消失。

该程序还创建一个日志文件,我将其命名为${logFolder}/${programName}_$$.log,因此它具有PIDShell 脚本的内容。

不幸的是,这些 pid 并不相同,因此如果程序没有清理其工作文件夹,我就没有简单的方法来找到与工作文件夹相对应的日志。

(我曾经通过查看日志文件中的 pid 来解决这个问题,awk并在脚本中重命名日志文件,但不幸的是,日志已更改并且不再包含 pid。)

编辑回应 Stéphane Chazelas

在实际情况下,日志是程序的标准输出。日志名称是参数之一。

此外,如果程序以返回码 1 结束,则脚本应以返回码 0 结束,以免在我们的作业调度系统中记录错误。

因此该脚本目前看起来更像是:

programName=<some calculation>
otherArguments=<other calculation>

"${programName}" -log "$logFolder/${programName}_$$.log" "${otherArguments}"
rc=$?
if [ $rc -eq 1 ]; then
        exit 0
else
        exit $rc
fi

之后我还能处理返回码吗?

exec "${programName}" -log "$logFolder/${programName}_$$.log" "${otherArguments}"

答案1

如果你跑

exec "$programName" > "$logFolder/${programName}_$$.log" 2>&1

那么该程序将在同一个进程中执行$$

这显然是 shell 脚本要做的最后一件事。

如果脚本之后需要执行其他操作,您可以启动一个新sh进程来执行重定向并在同一进程中执行程序:

LOGPREFIX="$logFolder/$programName" sh -c '
  exec "$0" "$@" > "${LOGPREFIX}_$$.log" 2>&1
  ' "$progName" and some extra arguments if needed

printf>&2 '%s\n' "$progName terminated with $? exit status"

do-more-stuff-after-the-program-has-returned

或者,如果脚本的其余部分需要对程序的 pid 执行某些操作:

LOGPREFIX=$logFolder/$programName sh -c '
  exec "$0" "$@" > "${LOGPREFIX}_$$.log" 2>&1
  ' "$progName" and some args if needed &

pid="$!"
printf>&2 '%s\n' "$progName was started asynchronously with pid $pid"
wait "$pid"
exit_status="$?"
printf>&2 '%s\n' "$progName terminated with exit status $exit_status"

请注意,在大多数 shell 中,异步启动命令会产生将其标准输入重定向到 /dev/null 的副作用。

相关内容