Bash - 启动和终止进程
Posted
技术标签:
【中文标题】Bash - 启动和终止进程【英文标题】:Bash - starting and killing processes 【发布时间】:2011-02-21 13:39:31 【问题描述】:我需要一些关于“简单”bash 脚本的建议。
我想启动一个程序“myprog”的大约 500 个实例,并在 x 秒后杀死所有实例
简而言之,我有一个在后台启动程序的循环,并在sleep x
(秒数)之后使用程序名称调用pkill
。
我的问题是:
如何验证 10 秒后所有 500 个实例都在运行? ps 和 grep 结合计数还是有其他方法?
如何计算 pkill(或类似的 kill 函数)实际杀死了多少进程(这样就没有任何进程在实际时间限制之前终止)?
如何重定向pkill(或类似的kill函数)的输出,使其不输出被杀死的进程信息,从而避免./initializeTest: line 250: 7566 Terminated ./$myprog
的500行。重定向到 /dev/null 没有成功。
【问题讨论】:
请看Process Management。 【参考方案1】:在 bash 中有 ulimit
命令控制(子)shell 的资源。
例如,保证最多使用 10 秒的 cpu 时间然后死:
(ulimit -t 10; ./do_something)
这并不能回答您的问题,但希望对您有所帮助。
【讨论】:
保证?我可以退款吗?time (ulimit -t 3; sleep 7)
输出:7.
@Dennis:但这并没有占用太多 CPU 时间吗? :)
但是 OP 询问的是实时性。
@Dennis:(a) 我知道,这就是为什么我说“这不能回答你的问题”,(b) OP 的流程可能比 sleep
和 (c) ulimit
的许多其他选项在这里可能有用。【参考方案2】:
1,2。使用pgrep
。我不记得pgrep
是否有-c
参数,所以你可能需要将它传递给wc -l
。
3:该输出是由你的 shell 的作业控制产生的。我认为如果您将其作为脚本运行(而不是在交互式外壳中),则不应该有这样的输出。对于交互式 shell,有多种方法可以关闭它,但它们取决于 shell,因此请参阅 shell 手册。
【讨论】:
感谢您的有用提示。 pgrep 确实有 -c 标志,并给出与 ps | 相同的结果。 grep 组合。从现在开始将使用它来使内容更具可读性。 @Milan:这不仅更具可读性,而且实际上更可靠。 (例如,ps | grep combo
可能与 grep
本身匹配,因为 combo
在其命令行中。)
确实如此。当我计算实例时,我总是使用 grep [x]xxx ,但是当我累了时可能会错过它。输出确实是由我的 shell 的作业控制产生的。这就解释了为什么我的“重定向”失败了。感谢您提供非常有用的信息。【参考方案3】:
好吧,我的 2 美分:
-
ps 和 grep 可以完成这项工作。顺便说一句,我发现 kill -0 $pid 更好:)(它会告诉您进程是否正在运行)
您可以使用 ps/grep 或 kill -0。对于您的问题,我将在后台启动所有进程并使用
$!
获取它们的pid,将它们存储在数组或列表中,然后使用kill -0
获取所有进程的状态。
使用&>
或2>&1
,因为它可能写在stderr 上
my2c
【讨论】:
感谢您的快速回复。当我尝试重定向时,我使用 &> 来重定向所有不起作用的输出。重定向到标准输出,然后重定向到 /dev/null 也不起作用。【参考方案4】:为了确保每个进程在被杀死之前获得公平的 10 秒份额,我会将每个命令用它自己的 sleep && kill
包装在一个子 shell 中。
function run_with_tmout
CMD=$1; TMOUT=$2
$CMD &
PID=$!
sleep $TMOUT
kill $PID
for ((i=0; i < 500; i++)); do
run_with_tmout ./myprog 10 &
done
# wait for all child processes to end
wait && echo "all done"
有关更完整的示例,请参阅this example from bashcookbook.com,它首先检查进程是否仍在运行,然后在诉诸SIGKILL
之前尝试kill -s SIGTERM
。
【讨论】:
如果kill -0
失败,这意味着该PID 上没有进程。它不会试图杀死进程;它只是检查是否存在。你应该做 SIGTERM、SIGQUIT、SIGINT、SIGHUP before you do SIGKILL。
谢谢丹尼斯,我错误地引用了这个例子。固定答案。【参考方案5】:
我一直在使用类似以下的方法来获取 pid 列表。
PS=$(ps ax | sed s/^' '*// | grep java | grep program_name | cut -d' ' -f1)
然后我使用kill $PS
阻止他们。
!/bin/bash
PS=$(ps ax | sed s/^' '*// | grep java | grep program_name | cut -d' ' -f1)
kill $PS
【讨论】:
以上是关于Bash - 启动和终止进程的主要内容,如果未能解决你的问题,请参考以下文章