我想运行和配置一个类似于脚本中守护进程的进程。
我的 shell 是在 Cygwin 下模拟 zsh 的,守护进程是SFK,一个基本的FTP服务器。
对于这里重要的事情,脚本startserv.sh
可以起草如下:
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
$cmd &
运行脚本后startserv.sh
,它停止(结束?),没有显示任何提示,然后:
CTRL+C结束脚本和后台作业进程;
点击Enter脚本结束进程仍保留在后台。
无论如何,我只能通过ps
而不是看到它jobs
,所以,当我想关闭进程时,我必须发送一个残酷的kill -9
信号,这是我想避免的有利于 CTRL+ 的事情C。
替代 将会在后台运行整个脚本。 “将是”,但read
如果脚本作为 运行,则该命令无法获取用户输入startserv.sh &
。
请注意,我需要一个临时服务器,而不是真正的服务器守护进程:也就是说,我希望服务器进程在后台运行,在脚本结束后执行简单的交互式 shell 任务(使用虚拟机来宾),但我不需要该进程在 shell 中存活;因此nohup
似乎不合适。
答案1
点击Enter脚本结束进程仍保留在后台。
几乎!实际上,当您按 时脚本已经退出Enter。但是,这就是您可以恢复提示符的方法(因为您的 shell 会$PS1
再次打印它)。
之所以点击Ctrl+C会终止它们两个,是因为它们两个是链接的。当您执行脚本时,您的 shell 会启动一个子 shell 来运行它。当您终止此子 shell 时,您的后台进程可能会因信号而终止SIGHUP
。
将脚本、后台进程和子shell分开
使用nohup
,您也许能够摆脱这个小小的不便。
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &
另一种disown
选择
如果您可以从 切换/bin/sh
到/bin/bash
,您也可以尝试一下disown
。要了解更多信息,只需输入help disown
一个bash
实例即可。
disown -h $cmd &
“很好地”终止后台进程
现在,当涉及到终止进程时,您可以使用 完美地执行“ Ctrl+ C” kill
。只是不要发送残酷的信息SIGKILL
。相反,您可以使用:
$ kill -2 [PID]
$ kill -15 [PID]
这将向您的进程发送一个很好的SIGINT
(2) 或(15)。SIGTERM
您可能还想在启动进程后打印 PID 值:
...
nohup $cmd &
echo $!
...或者更好的是,让脚本等待 a SIGINT
,然后将其发送回后台进程(这将使您的脚本保持在前台):
#!/bin/sh
read -s -p "Enter Password: " pw
user=testuser
share=/fshare
cmd="sfk ftpserv -user=$user -pw=$pw -usedir $share=$share"
nohup $cmd &
# Storing the background process' PID.
bg_pid=$!
# Trapping SIGINTs so we can send them back to $bg_pid.
trap "kill -2 $bg_pid" 2
# In the meantime, wait for $bg_pid to end.
wait $bg_pid
如果 aSIGINT
不够,只需使用 aSIGTERM
代替 (15) :
trap "kill -15 $bg_pid" 2 15
这样,当您的脚本收到后台进程的SIGINT
( Ctrl+ C, kill -2
) 或SIGTERM
while wait
ing 时,它只会将信号中继给它。如果这些信号确实杀死了sfk
实例,那么wait
调用将返回,因此也会终止您的脚本:)