在后台运行任务并了解其终止时间

在后台运行任务并了解其终止时间

我需要my_script在后台运行 unix shell 脚本 ( ) 并从 Web 界面监视它。

我从 php 启动实际脚本,如下所示:

$command = 'my_script';
$pid= exec("nohup {$command} > {$logFile} & echo $!");

然后$pid包含我的进程的 pid,我可以通过检查来了解该进程是否仍在运行file_exists("/proc/{$pid}")

然而,问题是:如何知道进程何时终止以及终止时运行了多长时间?

另外,有没有一个好方法可以找出该过程何时开始?我可以在调用之前或之后用 PHP 记录时间戳exec,但这会有些不准确。

编辑:

需要澄清的是,PHP 脚本不能等待 shell 脚本完成。 shell脚本需要在后台运行。我可能可以将三个命令(记录开始时间、运行时间my_script、记录完成时间)包装到一个 shell 中并将sh -c其传递给nohup,但我希望整个序列是原子的,这样我就不会最终只记录开始时间(如果有的话)出错。

答案1

您需要摆脱中间 shell 并将其作为您的直接子级启动,可能使用类似的东西proc_open(我不是 PHP 专家)。然后SIGCHLD当孩子终止时你会得到 a 。您可以为它安装一个信号处理程序(pcntl_signal最有可能),并在其中以非阻塞方式 ( WNOHANG) wait ( pcntl_waitpid) 您孩子的 PID,如果等待成功,记录时间并删除信号处理程序。

file_exists("/proc/{$pid}")如果你不控制wait调用(如果pid不是你的孩子),那么它是不可靠的,因为 PID 会被回收。

答案2

这似乎需要 at/batch,因为您使用的是 Web 前端。结果可以通过电子邮件发送给用户,也可以由用户查询(使用客户端 JavaScript 或只是简单的基于用户的检查)。

答案3

记录脚本退出条件的最简单方法是让它记录它们。

#!/bin/sh
trap 'date +"
    My name is $0. My PID is $$.
    My start time was '"$(date)."'
    The time is now %X on %x.
    My exit code is $?. Goodbye.
"   >/tell/somebody' EXIT
: now do some stuff

EXIT 陷阱应该适用于所有退出场景,但由信号杀死

如果您无法编辑相关脚本,只需将脚本包装在您可以控制其指令的 shell 中 - 例如sh -c您提到的:

trap=': the trap' sh -c '
trap "$trap" 0;. "$0"'   \
    ./script/i/cant/edit \
    positional params    &

类似的事情可以用 w/ 完成sh -s,但 的值$0可能不像控制那么简单。对于某些 shell,您需要exec一个新的 infile/替换 shell 才能更改它(我有时使用符号链接和PATH=.w/exec来更改/删除进程名称中的所有路径组件)

echo 'trap "$trap" EXIT'   |
cat - ./script/i/cant/edit | 
trap=': the trap' sh -s -- \
    positional params go here &

相关内容