2010-12-06 94 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

相關問題