我有一个脚本应该停止并恢复在后台运行的进程:
process_id=`ps -eaf | grep -i daemon | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
(kill -STOP $process_id) &
... # do something else
(kill -CONT $process_id) &
这工作正常,但随后在 STDOUT / STDERR 中出现:
[1] + 8545 Suspended (signal) /etc/init.d/...
到目前为止我尝试:
(kill -STOP $process_id)
(kill -STOP $process_id) & > /dev/null
/etc/init.d/{name_of_the_daemon} start > /dev/null
(kill -STOP $process_id & ) 2>/dev/null
(kill -STOP $process_id & disown;) 2>/dev/null
set +m
(kill -STOP $process_id) &
(kill -STOP $process_id) & 1>&2
这些是我正在执行的步骤:
- 创建一个文件 fff 在
/etc/init.d/
- 粘贴下面的脚本
chmod 755 fff
- /etc/init.d/fff 启动
之后,我收到“暂停”消息......
根据@sourcejedi,我的脚本不是守护进程;当脚本的子进程被挂起时,会出现“挂起”消息
我怎样才能抑制 shell 中仅输出的那条特定消息?
这是我的脚本的一个非常简单的版本:
#!/bin/bash
pid_script=`ps -eaf | grep -i fff | grep -v grep | grep -v status | grep -v stop | awk '{print $2}'`
case "$1" in
start)
( sleep 3; kill -STOP $pid_script ) &
sleep 10;
(sleep 1; kill -CONT $pid_script) &
;;
stop)
for p in $pid_script # kill all the other processes related with this script (if any)
do
kill -9 $p
done
esac
答案1
当您看到 时[1] + 7766 Suspended (signal) ...
,这是 shell 打印的一条消息,告诉您它的一个子进程已被挂起。
在fff
示例中,需要考虑两个 shell 进程。您的初始交互式 shell 以及作为子进程运行的 shell 脚本。
您的脚本安排自行挂起。交互式 shell 打印“挂起”消息。所以这不是一个可以打开或关闭的选项在脚本里面。
此外,您无法在交互式 shell 中设置选项来打开或关闭此特定消息。不可能单独“抑制”此消息......基本上是因为这永远不是您想要做的:-)。
我认为fff
脚本无论如何都无法成功恢复自身。我认为可以对其进行修改以实现此目的。然而,恢复本身是一个糟糕的主意。当您暂停脚本时,交互式 shell 会再次显示其命令提示符。即,如果您没有看到“暂停”消息,则看起来您的脚本已完成。但无论哪种方式,如果您的脚本设法自行恢复,它都会尝试从用户那里夺回对终端的控制权,无论他们同时开始做什么。不是很好!
我认为您需要了解,例如,如果您从终端启动了一个进程,并且它是一个交互式 shell 的子进程,那么它绝对不是一个守护进程过程。
开始一个守护进程从您的终端,程序必须在启动期间自行 fork() 。原来的进程应该退出,这允许继续运行的进程重新养育例如(在传统的 unix 中)PID 1 又名进程init
。它还必须包括更多步骤才能从终端分离。参见此处的示例:在 shell 中守护进程?
此外,如果您的系统使用systemd
,您需要了解/etc/init.d/
需要使用旧脚本来启动systemctl start
。 Debian 和其他地方的打包init.d
脚本包含一个兼容性 hack,可以为您完成此操作。但你应该不是使用该功能。这是造成混乱的秘诀。你写的脚本没有这个功能,所以你必须使用systemctl start fff
。
我强烈建议不要尝试将脚本中的游戏fff
与systemctl start
.
实际上systemctl
使用不同的方法来启动后台服务进程。它向PID 1(init进程)发送消息systemd
,PID 1启动所请求的程序。如果您定义了本机 systemd 服务,则程序不需要自行守护进程。如果您使用旧init.d
脚本,程序仍然需要对自身进行守护进程,但它实现的唯一作用是告诉systemd
脚本init.d
已完成启动。 (这使得可以注意到守护进程中的一些启动失败,但不幸的是,许多现有程序在守护进程步骤之后可能会发生启动失败)。
您不想担心脚本是否以及如何systemd
对init.d
脚本自行停止和恢复做出反应。
答案2
不确定我是否正确理解你的目标,但这对我来说是这样的:
启动“守护进程”,实际上只是持续运行的进程:
top -d1 >out
tail -f out
如果您愿意,可以在第二个航站楼- 在我运行的第三个终端中
kill -STOP $(ps -eFH | grep "top -d" |grep -v grep|awk '{print $2}'
您将在启动守护程序的第一个终端中看到“挂起”消息,但在文件中out
不会有此类消息。