17

我想要做的是编写一个Bash 脚本,在使用 mac say命令说出一些文本之前,它会休眠一段时间。

我希望能够运行该命令,然后关闭终端,这样它仍然会在设定的时间说话。我研究了 nohup、分离、启动并将进程置于后台,但所有这些解决方案仍然会导致进程在终端关闭后终止。我应该以某种方式制作某种僵尸子进程来执行此操作吗?什么是最好的解决方案?谢谢

# Simple Example of main code
sleep 10;
say hello;
exit;
4

8 回答 8

13

Bash 手册的第 3.7.6 节说:

shell 在收到 SIGHUP 后默认退出。在退出之前,交互式 shell 会将 SIGHUP 重新发送到所有正在运行或停止的作业。停止的作业被发送 SIGCONT 以确保它们收到 SIGHUP。为防止 shell 将 SIGHUP 信号发送到特定作业,应使用 disown 内置函数将其从作业表中删除(参见第 7.2 节 [Job Control Builtins],第 88 页)或使用 标记为不接收 SIGHUP disown -h

因此,使用其中一个nohupdisown应该可以解决问题。或者你可以这样做:

trap "" 1
sleep 10
say hello

' trap' 行忽略信号 1,SIGHUP;你也可以写' trap "" HUP"。

于 2010-12-06T19:00:16.723 回答
12
nohup yourscript.sh 10 "hello" &

#     ^your script  ^^your parameter 1
#                      ^^^^^^^your parameter 2

这会将脚本与终端分离,并且在终端关闭时不会被终止。注意&最后; 您可以正常将参数传递给您的脚本。那么 yourscript.sh 可能是:

#!/bin/bash

sleep $1;
say "$2";
exit;
于 2010-12-06T18:56:11.443 回答
6

如果你没有像已经建议的那样以 开头nohup,你需要这样使用disown......

$ ./say-hello.sh &
[1] 12345
$ disown -h %1

您需要记下作业编号(上例中的第二行,作业编号在括号中,另一行是进程 ID),以便您可以将其传递给disown.

于 2010-12-06T19:06:00.260 回答
6

您需要将 nohup 和 background 一起使用。我刚刚在 OS-X 上试过这个来验证它是否有效:

nohup ./say-hello.sh &
于 2010-12-06T18:57:01.500 回答
3
于 2010-12-06T20:18:34.530 回答
1

这里的所有解决方案都非常好,但是它们没有提供一种简单的方法来“查看”程序中发生的事情,而无需进行会填满硬盘驱动器的重定向。

使用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命令末尾的 。

于 2017-03-30T23:11:37.810 回答
0

根据您对“简单”的定义,答案可能是daemon

于 2010-12-06T21:16:31.780 回答
0

nohup yourscript.sh &按照 Piskvor 的建议使用。

但是,请注意,您将无法重新获得对流程的“控制”。因此,如果您确实需要它,我建议将日志记录添加到文件中,以便您知道程序在做什么。

如果没有 ,可能无法杀死您的程序kill -9,这可能有点残酷。如果您不希望这样,我建议end.txt每隔一分钟左右汇集一个文件。如果你的程序检测到它的工作目录中存在这样的文件,它应该正常退出。

于 2010-12-06T19:16:15.120 回答