Linux中長時間執行指令碼或者命令

2021-07-03 11:11:49 字數 4080 閱讀 1488

nohup/setsid/&

場景:如果只是臨時有乙個命令需要長時間執行,什麼方法能最簡便的保證它在後台穩定執行呢?

解決方法:

我們知道,當使用者登出(logout)或者網路斷開時,終端會收到 hup(hangup)訊號從而關閉其所有子程序。

因此,我們的解決辦法就有兩種途徑:要麼讓程序忽略 hup 訊號,要麼讓程序執行在新的會話裡從而成為不屬於此終端的子程序。

1. nohup

nohup(1)                        user commands                        nohup(1)

name

nohup - run a command immune to hangups, with output to a non-tty

synopsis

nohup command [arg]...

nohup option

description

run command, ignoring hangup signals.

nohup 無疑是我們首先想到的辦法。顧名思義,nohup 的用途就是讓提交的命令忽略 hangup 訊號。

只需在要處理的命令前加上 nohup 即可,標準輸出和標準錯誤缺省會被重定向到 nohup.out 檔案中。一般我們可在結尾加上"&"來將

命令同時放入後台執行,也可用">filename 2>&1"來更改預設的重定向檔名。

2。setsid

nohup 無疑能通過忽略 hup 訊號來使我們的程序避免中途被中斷,但如果我們換個角度思考,如果我們的程序不屬於接受 hup 訊號的

終端的子程序,那麼自然也就不會受到 hup 訊號的影響了。setsid 就能幫助我們做到這一點。

setsid(8)                 linux programmer』s manual                 setsid(8)

name

setsid - run a program in a new session

synopsis

setsid program [ arg ... ]

description

setsid runs a program in a new session.

setsid 的使用也是非常方便的,也只需在要處理的命令前加上 setsid 即可。

[root@pvcent107 ~]# setsid ping www.ibm.com

[root@pvcent107 ~]# ps -ef |grep www.ibm.com

root     31094     1  0 07:28 ?        00:00:00 ping www.ibm.com

root     31102 29217  0 07:29 pts/4    00:00:00 grep www.ibm.com

3。&這裡還有乙個關於 subshell 的小技巧。我們知道,將乙個或多個命名包含在「()」中就能讓這些命令在子 shell 中執行中,從而擴充套件出很多

有趣的功能,我們現在要討論的就是其中之一。

當我們將"&"也放入「()」內之後,我們就會發現所提交的作業並不在作業列表中,也就是說,是無法通過jobs來檢視的。讓我們來看看

為什麼這樣就能躲過 hup 訊號的影響吧。

subshell 示例

[root@pvcent107 ~]# (ping www.ibm.com &)

[root@pvcent107 ~]# ps -ef |grep www.ibm.com

root     16270     1  0 14:13 pts/4    00:00:00 ping www.ibm.com

root     16278 15362  0 14:13 pts/4    00:00:00 grep www.ibm.com

[root@pvcent107 ~]#

從上例中可以看出,新提交的程序的父 id(ppid)為1(init 程序的 pid),並不是當前終端的程序 id。因此並不屬於當前終端的子程序,

從而也就不會受到當前終端的 hup 訊號的影響了。

disown

場景:我們已經知道,如果事先在命令前加上 nohup 或者 setsid 就可以避免 hup 訊號的影響。但是如果我們未加任何處理就已經提交了命令,

該如何補救才能讓它避免 hup 訊號的影響呢?

解決方法:

這時想加 nohup 或者 setsid 已經為時已晚,只能通過作業排程和 disown 來解決這個問題了。

用disown -h jobspec來使某個作業忽略hup訊號。

用disown -ah 來使所有的作業都忽略hup訊號。

用disown -rh 來使正在執行的作業忽略hup訊號。

需要注意的是,當使用過 disown 之後,會將把目標作業從作業列表中移除,我們將不能再使用jobs來檢視它,但是依然能夠用ps -ef查詢到它。

但是還有乙個問題,這種方法的操作物件是作業,如果我們在執行命令時在結尾加了"&"來使它成為乙個作業並在後台執行,那麼就萬事大吉了,

我們可以通過jobs命令來得到所有作業的列表。但是如果並沒有把當前命令作為作業來執行,如何才能得到它的作業號呢?答案就是用 ctrl-z

(按住ctrl鍵的同時按住z鍵)了!

ctrl-z 的用途就是將當前程序掛起(suspend),然後我們就可以用jobs命令來查詢它的作業號,再用bg jobspec來將它放入後台並繼續執行。

需要注意的是,如果掛起會影響當前程序的執行結果,請慎用此方法。

disown 示例1(如果提交命令時已經用「&」將命令放入後台執行,則可以直接使用「disown」)

[root@pvcent107 build]# cp -r testlargefile largefile &

[1] 4825

[root@pvcent107 build]# jobs

[1]+  running                 cp -i -r testlargefile largefile &

[root@pvcent107 build]# disown -h %1

[root@pvcent107 build]# ps -ef |grep largefile

root      4825   968  1 09:46 pts/4    00:00:00 cp -i -r testlargefile largefile

root      4853   968  0 09:46 pts/4    00:00:00 grep largefile

[root@pvcent107 build]# logout

disown 示例2(如果提交命令時未使用「&」將命令放入後台執行,可使用 ctrl-z 和「bg」將其放入後台,再使用「disown」)

[root@pvcent107 build]# cp -r testlargefile largefile2

[1]+  stopped                 cp -i -r testlargefile largefile2

[root@pvcent107 build]# bg %1

[1]+ cp -i -r testlargefile largefile2 &

[root@pvcent107 build]# jobs

[1]+  running                 cp -i -r testlargefile largefile2 &

[root@pvcent107 build]# disown -h %1

[root@pvcent107 build]# ps -ef |grep largefile2

root      5790  5577  1 10:04 pts/3    00:00:00 cp -i -r testlargefile largefile2

root      5824  5577  0 10:05 pts/3    00:00:00 grep largefile2

[root@pvcent107 build]#

總結現在幾種方法已經介紹完畢,我們可以根據不同的場景來選擇不同的方案。nohup/setsid 無疑是臨時需要時最方便的方法,

disown 能幫助我們來事後補救當前已經在執行了的作業

Linux中長時間執行程式的方法

一 場景 如果臨時有乙個命令需要長時間執行,比如 python hello.py 什麼方法能最簡便的保證它在後台穩定執行呢?解決方法 當使用者登出 logout 或者網路斷開時,終端會收到 hup hangup 訊號從而關閉其所有子程序。因此,我們的解決辦法就有兩種途徑 要麼讓程序忽略 hup 訊號...

防止shell指令碼長時間執行導致ssh超時

在一些對安全性要求較高的場景下。ssh的超時時間是管理員預先設定好的,在閒置一段時間後ssh連線會自己主動斷開。這樣的情況下假設通過ssh執行指令碼,而指令碼執行時間又比較長的話。會導致sshclient和server長時間無互動而超時,命令執行失敗。使用bash子程序能夠解決這樣的問題,思路是由子...

Linux執行指令碼

首先指令碼需要有執行許可權 chmod u x file.sh 執行指令碼有三種方法 1.file.sh 特點 開啟bash子程序來執行,也就是開啟額外的程序來進行,不影響原程序的變數 配置等 2.bash file.sh 特點 和.file.sh相同 3.source file.sh 或者 fil...