ant*_*nio 15 command-line signals job-control shell-script background-process
我想从脚本运行和配置一个类似于守护进程的进程。
我的 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 &
Run Code Online (Sandbox Code Playgroud)
运行脚本后startserv.sh,它停止(结束?)而不显示任何提示,然后:
CTRL+C结束脚本和后台作业进程;
点击Enter脚本结束该过程保留在后台。
无论如何,我只能通过ps而不能看到它jobs,所以,当我想关闭进程时,我必须发送一个残酷的kill -9信号,这是我想避免的事情,以支持 CTRL+ C。
另一种方法 是在后台运行整个脚本。'Would be',但read如果脚本作为startserv.sh &.
请注意,我需要一个临时服务器,而不是真正的守护进程:也就是说,我希望服务器进程在脚本结束后在后台运行,以执行简单的交互式 shell 任务(使用虚拟机来宾),但我不不需要进程在 shell 中存活;因此nohup似乎不合适。
Joh*_*ith 19
点击Enter脚本结束该过程保留在后台。
几乎!实际上,当您按下 时,脚本已经退出Enter。但是,这就是您可以恢复提示的方法(因为您的 shell 会$PS1再次打印它)。
之所以打Ctrl+C终止他们两个,是因为他们两个是有联系的。当您执行脚本时,您的 shell 会启动一个子 shell 来运行它。当你终止这个子shell时,你的后台进程可能会因为一个SIGHUP信号而死亡。
使用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 &
Run Code Online (Sandbox Code Playgroud)
disown替代如果您可以从 切换/bin/sh到/bin/bash,您也可以尝试一下disown。要了解更多信息,只需输入help disown一个bash实例。
disown -h $cmd &
Run Code Online (Sandbox Code Playgroud)
现在,当涉及到杀死你的过程中,你可以完全做一个“ Ctrl+ C”使用kill。只是不要发送一个残酷的SIGKILL。相反,您可以使用:
$ kill -2 [PID]
$ kill -15 [PID]
Run Code Online (Sandbox Code Playgroud)
这将向您的流程发送一个很好的SIGINT(2) 或SIGTERM(15)。您可能还想在启动过程后打印 PID 值:
...
nohup $cmd &
echo $!
Run Code Online (Sandbox Code Playgroud)
...或者更好的是,让脚本等待 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
Run Code Online (Sandbox Code Playgroud)
如果 aSIGINT不够,只需使用 aSIGTERM代替 (15) :
trap "kill -15 $bg_pid" 2 15
Run Code Online (Sandbox Code Playgroud)
这样,当您的脚本接收到SIGINT( Ctrl+ C, kill -2) 或SIGTERMwhilewait后台进程时,它只会将信号转发给它。如果这些信号确实杀死了sfk实例,则wait调用将返回,因此也会终止您的脚本:)