我需要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 &