“分离/守护”Bash 脚本的最简单方法是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4369866/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the easiest way to "detach/daemonize" a Bash script?
提问by Warpling
What I am trying to do is write a Bash scriptthat sleepsfor a set amount of time before using the mac saycommand to speak some text.
我想要做的是编写一个Bash 脚本,在使用 mac say命令说出一些文本之前,该脚本会休眠一段时间。
I'd like to be able to run the command and then close the terminal so it will still speak at the set time. I've looked into nohup, detach, launchd, and putting the process in the background, but all of these solutions still result in the process being terminated once the terminal is closed. Should I somehow make some sort of zombie child process to do this? What is the best solution? Thank you
我希望能够运行命令,然后关闭终端,这样它仍然会在设定的时间说话。我已经研究过 nohup、detach、launchd 和将进程置于后台,但所有这些解决方案仍然会导致一旦终端关闭,进程就会终止。我应该以某种方式制作某种僵尸子进程来做到这一点吗?最好的解决方案是什么?谢谢
# Simple Example of main code
sleep 10;
say hello;
exit;
采纳答案by Jonathan Leffler
Section 3.7.6 of the Bash Manual says:
Bash 手册的第 3.7.6 节说:
The shell exits by default upon receipt of a SIGHUP. Before exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure that they receive the SIGHUP. To prevent the shell from sending the SIGHUP signal to a particular job, it should be removed from the jobs table with the disown builtin (see Section 7.2 [Job Control Builtins], page 88) or marked to not receive SIGHUP using
disown -h
.
shell 在收到 SIGHUP 后默认退出。在退出之前,交互式 shell 将 SIGHUP 重新发送到所有正在运行或已停止的作业。停止的作业被发送 SIGCONT 以确保它们收到 SIGHUP。为防止 shell 向特定作业发送 SIGHUP 信号,应使用 disown 内置函数将其从作业表中删除(请参阅第 7.2 节 [作业控制内置函数],第 88 页)或使用 标记为不接收 SIGHUP
disown -h
。
So, using either nohup
or disown
should do the trick. Or you can do:
因此,使用nohup
ordisown
应该可以解决问题。或者你可以这样做:
trap "" 1
sleep 10
say hello
That 'trap
' line ignores signal 1, SIGHUP; you can probably also write 'trap "" HUP
".
' trap
' 行忽略信号 1, SIGHUP; 你可能也可以写' trap "" HUP
"。
回答by Piskvor left the building
nohup yourscript.sh 10 "hello" &
# ^your script ^^your parameter 1
# ^^^^^^^your parameter 2
This will detach the script from the terminal, and it won't be killed when the terminal closes. Note the &
at the end; you can pass parameters to your script normally. Then yourscript.sh could be:
这会将脚本与终端分离,并且不会在终端关闭时被杀死。注意&
最后的; 您可以正常将参数传递给您的脚本。那么 yourscript.sh 可能是:
#!/bin/bash
sleep ;
say "";
exit;
回答by Laurence Gonsalves
You need to use nohup and background together. I just tried this on OS-X to verify that it works:
您需要将 nohup 和 background 一起使用。我只是在 OS-X 上试过这个来验证它是否有效:
nohup ./say-hello.sh &
回答by Will
If you do not start it with nohup
, as already suggested, you would need to use disown
as such ...
如果您没有nohup
像已经建议的那样以开头,则需要这样使用disown
...
$ ./say-hello.sh &
[1] 12345
$ disown -h %1
You will need to make note of the job number (the second line in the example above, the job number is in the brackets and the other is the process id) so that you can pass it to disown
.
您需要记下作业编号(上面示例中的第二行,作业编号在括号中,另一行是进程 ID),以便您可以将其传递给disown
.
回答by Paused until further notice.
Your script could look like this:
您的脚本可能如下所示:
#!/bin/bash
read -p "Text: " text
read -p "Delay: " delay
nohup bash -c "sleep $delay; say \"$text\" &"
Then you would run your script normally:
然后你会正常运行你的脚本:
$ your_script
Text: hello
Delay: 10
and the outer script would exit, but the Sleep&Say?
would be left running in the background.
并且外部脚本将退出,但Sleep&Say?
将在后台运行。
回答by tobiasBora
All the solution here are very good, but they don't provide an easy way to "look" what happen in the program without doing a redirection that would fill the hard drive.
这里的所有解决方案都非常好,但是它们没有提供一种简单的方法来“查看”程序中发生的情况,而无需进行会填充硬盘驱动器的重定向。
Using screen
you can then very easily run a script, close your terminal/ssh session, and then come back latter, and "attach" again to the script. Do do that it's pretty easy.
使用screen
您可以非常轻松地运行脚本,关闭您的终端/ssh 会话,然后返回,并再次“附加”到脚本。这样做很容易。
Install
安装
First install screen
:
首先安装screen
:
sudo apt-get install screen
Detach
分离
and then put in your bash file
然后放入你的 bash 文件
#!/usr/bin/env bash
screen -S myscreen -d -m bash -c 'ls; exec bash'
(replace ls
with your program) It will create (-S
) a "screen" named myscreen
, and detach it (-d
) by running the commands inside the ``-c``` option. Then if you want to connect later to this screen:
(替换ls
为您的程序)它将创建 ( -S
) 一个名为 的“屏幕” myscreen
,并-d
通过运行 ``-c``` 选项中的命令将其分离 ( )。然后,如果您想稍后连接到此屏幕:
And attach later
稍后附上
screen -rd myscreen
if you want to list all screen currently running:
如果要列出当前正在运行的所有屏幕:
screen -ls
NB: if you want to close the screen when it's finished, remove the bash
at the end of the command.
注意:如果您想在完成后关闭屏幕,请删除bash
命令末尾的 。
回答by sorpigal
回答by darioo
Use nohup yourscript.sh &
as Piskvor suggested.
nohup yourscript.sh &
按照 Piskvor 的建议使用。
However, note that you won't be able to regain "control" of your process. Therefore, if you do need it, I suggest adding logging to a file so you know what your program is doing.
但是,请注意,您将无法重新获得对流程的“控制权”。因此,如果您确实需要它,我建议将日志记录添加到文件中,以便您了解您的程序在做什么。
Killing your program might not be possible without kill -9
, and that might be a bit brutal. If you don't want that, I'd suggest pooling for a file like end.txt
every minute or so. If your program detects presence of such a file in it's working directory, it should exit gracefully.
没有 可能无法杀死您的程序kill -9
,这可能有点残酷。如果您不希望那样,我建议end.txt
每隔一分钟左右就汇集一个文件。如果您的程序在其工作目录中检测到此类文件的存在,它应该正常退出。