我想要做的是编写一个Bash 脚本,在使用 mac say命令说出一些文本之前,它会休眠一段时间。
我希望能够运行该命令,然后关闭终端,这样它仍然会在设定的时间说话。我研究了 nohup、分离、启动并将进程置于后台,但所有这些解决方案仍然会导致进程在终端关闭后终止。我应该以某种方式制作某种僵尸子进程来执行此操作吗?什么是最好的解决方案?谢谢
# Simple Example of main code
sleep 10;
say hello;
exit;
Bash 手册的第 3.7.6 节说:
shell 在收到 SIGHUP 后默认退出。在退出之前,交互式 shell 会将 SIGHUP 重新发送到所有正在运行或停止的作业。停止的作业被发送 SIGCONT 以确保它们收到 SIGHUP。为防止 shell 将 SIGHUP 信号发送到特定作业,应使用 disown 内置函数将其从作业表中删除(参见第 7.2 节 [Job Control Builtins],第 88 页)或使用 标记为不接收 SIGHUP
disown -h
。
因此,使用其中一个nohup
或disown
应该可以解决问题。或者你可以这样做:
trap "" 1
sleep 10
say hello
' trap
' 行忽略信号 1,SIGHUP;你也可以写' trap "" HUP
"。
nohup yourscript.sh 10 "hello" &
# ^your script ^^your parameter 1
# ^^^^^^^your parameter 2
这会将脚本与终端分离,并且在终端关闭时不会被终止。注意&
最后; 您可以正常将参数传递给您的脚本。那么 yourscript.sh 可能是:
#!/bin/bash
sleep $1;
say "$2";
exit;
如果你没有像已经建议的那样以 开头nohup
,你需要这样使用disown
......
$ ./say-hello.sh &
[1] 12345
$ disown -h %1
您需要记下作业编号(上例中的第二行,作业编号在括号中,另一行是进程 ID),以便您可以将其传递给disown
.
您需要将 nohup 和 background 一起使用。我刚刚在 OS-X 上试过这个来验证它是否有效:
nohup ./say-hello.sh &
这里的所有解决方案都非常好,但是它们没有提供一种简单的方法来“查看”程序中发生的事情,而无需进行会填满硬盘驱动器的重定向。
使用screen
您可以非常轻松地运行脚本,关闭您的终端/ssh 会话,然后稍后返回,并再次“附加”到脚本。这样做很容易。
首先安装screen
:
sudo apt-get install screen
然后放入你的bash文件
#!/usr/bin/env bash
screen -S myscreen -d -m bash -c 'ls; exec bash'
(替换ls
为您的程序)它将创建(-S
)一个名为 的“屏幕” ,并通过运行“-c”选项中的命令myscreen
将其分离( )。-d
然后,如果您想稍后连接到此屏幕:
screen -rd myscreen
如果要列出当前正在运行的所有屏幕:
screen -ls
注意:如果您想在完成后关闭屏幕,请删除bash
命令末尾的 。
根据您对“简单”的定义,答案可能是daemon。
nohup yourscript.sh &
按照 Piskvor 的建议使用。
但是,请注意,您将无法重新获得对流程的“控制”。因此,如果您确实需要它,我建议将日志记录添加到文件中,以便您知道程序在做什么。
如果没有 ,可能无法杀死您的程序kill -9
,这可能有点残酷。如果您不希望这样,我建议end.txt
每隔一分钟左右汇集一个文件。如果你的程序检测到它的工作目录中存在这样的文件,它应该正常退出。