2010-12-06 57 views
15

我所试图做的是写一个bash脚本了设定的时间量命令讲一些文本之前,使用MAC。什么是“分离/守护进程”Bash脚本的最简单方法?

我希望能够运行该命令,然后关闭终端,以便在设定的时间发言。我已经研究过nohup,detach,launchd,并将该流程置于后台,但所有这些解决方案仍会导致终端关闭后流程终止。我应该以某种方式让某种僵尸子进程执行此操作吗?什么是最好的解决方案?谢谢

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

回答

12

Bash的手册的第3.7.6节说:

通过在收到SIGHUP的默认外壳退出。在退出之前,交互式外壳程序 会将SIGHUP重新发送到所有正在运行或已停止的作业。停止的工作被发送到SIGCONT 确保他们收到SIGHUP。为了防止shell将SIGHUP信号 发送到特定作业,应该使用disown内建函数(请参见 第7.2节[作业控制内置函数],第85页)将其从作业表中删除,或者使用disown -h将其标记为不接收SIGHUP。

因此,使用nohupdisown应该做的伎俩。或者,你可以这样做:

trap "" 1 
sleep 10 
say hello 

trap'线忽略了信号1,SIGHUP;你可能也写'trap "" HUP”。

+0

谢谢,我不知道SIGHUP,但这是有道理的。这对我正在尝试做的事很好。 :) – Warpling 2010-12-06 19:25:46

11
nohup yourscript.sh 10 "hello" & 

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

这将从终端分离的脚本,当终端关闭它不会被杀死。最后请注意&;您可以正常将参数传递给脚本。然后yourscript.sh可能是:

#!/bin/bash 

sleep $1; 
say "$2"; 
exit; 
+0

我忽略提及,在我的脚本中,时间和消息是可变的。如果我像这样运行命令,我从来没有看到我的提示,也不能输入变量。 :/ – Warpling 2010-12-06 19:19:04

+0

@Warpling:编辑以表明您可以将params传递给nohup。 – Piskvor 2010-12-06 20:47:46

+0

非常好,谢谢:) – Warpling 2010-12-08 00:22:58

6

您需要一起使用nohup和背景。我只是尝试这样做的OS-X,以验证它的工作原理:

nohup ./say-hello.sh & 
+0

我忽略了在我的脚本中提到的时间和消息是可变的。如果我像这样运行命令,我从来没有看到我的提示,也不能输入变量。 :/ – Warpling 2010-12-06 19:20:30

3

如果你不nohup启动它,因为已经建议,你需要使用disown这样...

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

你需要记作业编号的(在上面的例子中的第二行中,作业数量在托架和另一个是进程ID),这样就可以将其传递给disown

0

使用nohup yourscript.sh &作为Piskvor建议。

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

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

2

你的脚本可能是这样的:

#!/bin/bash 
read -p "Text: " text 
read -p "Delay: " delay 
nohup bash -c "sleep $delay; say \"$text\" &" 

然后,你通常会运行脚本:

$ your_script 
Text: hello 
Delay: 10 

和外部脚本将退出,但Sleep&Say™将留在运行的背景。

0

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

0

这里的所有解决方案都非常好,但是他们没有提供一种简单的方法来“观察”程序中发生的情况,而无需执行重定向来填充硬盘驱动器。

使用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)名为“屏幕” myscreen,并通过运行``-c```选项中的命令来分离它(-d)。然后,如果你想在以后连接这个屏幕:

而且以后如果要列出当前运行的所有屏幕连接

screen -rd myscreen 

screen -ls 

注意:如果你想关闭屏幕完成后,请在命令结尾处删除bash

相关问题