2014-02-10 77 views
4

我在我的bashrc中有一個小函數,所以我可以運行一個腳本並在輸出完成後將輸出發送到我的電子郵件。代碼如下:bash nohup有兩個命令

run() { 
    [email protected] 
    last="${!#}" 
    rest="${@:1:($#-1)}" 

    (nohup $rest &> $last < /dev/null; mail -s "$rest" "$email" < "$last") & 
} 

功能用於這樣

run ./script.sh arg1 arg2 output 

,它似乎是工作的大部分時間,但有時即使腳本完成的電子郵件不會發送。我懷疑這與我關閉服務器終端有關。在這些情況下,由於nohup腳本仍在運行,但它不會在最後發送電子郵件。爲了讓它正常工作,我真的很感激一些指針。

+0

'rest =「$ {@:1:($# - 1)}」'是一個壞主意 - 你無法準確地表示一個標量的參數向量,所以這個運行可能會使用'rest =(「$ {@:1:($# - 1)}」)',然後使用'「擴展它」 $ {rest [@]}「'(或者,對於單參數主題行版本,」$ {rest [*]}「......或者更確切地說,是'printf -v rest_cmd'%q' 「$ {rest [@]}」',然後使用'「$ rest_cmd」'作爲郵件參數) –

+0

感謝您的提示,我肯定會改變這種情況。 – skd

回答

5

有解決這個多種方式,但我想我會推薦這:

run() { 
    [email protected] 
    rest="${@:1:($#-1)}" 

    nohup bash -c "$rest < /dev/null 2>&1 | mail -s \"$rest\" \"$email\"" & 
} 

問題是你nohup命令在分號/dev/null後結束,因此不適用於mail部分。 (...)引入了子shell,但不是外部命令,因此nohup (...)將不起作用,這就是爲什麼bash -c "..."是必需的(如果這很重要,您還可以使用${SHELL} -c " ..."增加可移植性)。用另一組引號括起來的雙引號需要轉義。此外,臨時文件不是必需的(除非你想保留它 - 出於某種原因 - 如果是這種情況,請隨意將重定向回來,並將命令與;而不是|分開)。在不需要輸出文件的情況下,您也可以免去rest=...位,只是將它稱爲run script.sh arg1 arg2,但是如果您已經打電話給其他代碼,則可能會更簡單一些 - 您必須確定那部分...

+0

謝謝!我實際上嘗試過'''nohup(...)''',我真的很困惑它不工作! – skd

+0

輸出文件對我很有用,所以我將腳本改爲'''nohup bash -c「$ rest&> $ last; mail -s \」$ rest \「\」$ email \「<\」$ last \ 「」&>/dev/null/dev/null''。 – skd