我写了一个 shell 脚本来启动一个程序${programName}
。
该程序恰好在文件夹 中创建临时工作文件,<workFolderLocation>/SAS_work<randomHex>00<pidHex>_<server>
其中是该程序pidHex
的十六进制表示形式。PID
通常,当程序完成时,这个临时文件夹就会消失。
该程序还创建一个日志文件,我将其命名为${logFolder}/${programName}_$$.log
,因此它具有PID
Shell 脚本的内容。
不幸的是,这些 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 的副作用。