在阿里云搭建了一個(gè)遠(yuǎn)程Jupyter Notebook服務(wù),但是每次關(guān)閉了jupyter服務(wù)的終端窗口或者ssh自動(dòng)斷開(kāi)連接的時(shí)候,會(huì)將jupyter服務(wù)掛斷。
這樣的場(chǎng)景我們經(jīng)常碰見(jiàn),折騰了一下,發(fā)現(xiàn)可以使用Linux中nohup
命令來(lái)守衛(wèi)程序,保證程序不受本地關(guān)閉終端窗口/網(wǎng)絡(luò)斷開(kāi)連接的干擾。
在講nohup
之前,先介紹一下Linux中前后臺(tái)任務(wù)的知識(shí)。
前臺(tái)任務(wù)
前臺(tái)任務(wù)是獨(dú)占命令行窗口的任務(wù),只有運(yùn)行完了或者手動(dòng)中止該任務(wù),才能執(zhí)行其他命令。比如我們開(kāi)了一個(gè)jupyter notebook, 這個(gè)命令行就被獨(dú)占了,無(wú)法執(zhí)行其他命令,除非關(guān)閉了jupyter,命令行才可以輸入其他命令。
后臺(tái)任務(wù)
與前臺(tái)任務(wù)相對(duì)應(yīng),后臺(tái)任務(wù)在運(yùn)行的時(shí)候,并不需要與用戶交互,它們通常在不打擾用戶其它工作的時(shí)候默默地執(zhí)行。使shell可以繼續(xù)響應(yīng)用戶的輸入。后臺(tái)任務(wù)繼承當(dāng)前會(huì)話的標(biāo)準(zhǔn)輸出(stdout)和標(biāo)準(zhǔn)錯(cuò)誤(stderr)。因此,后臺(tái)任務(wù)的所有輸出依然會(huì)同步地在命令行下顯示。不再繼承當(dāng)前session的標(biāo)準(zhǔn)輸入(stdin),你無(wú)法向這個(gè)任務(wù)輸入指令了。如果它試圖讀取標(biāo)準(zhǔn)輸入,就會(huì)暫停執(zhí)行。
可以看出,”后臺(tái)任務(wù)”與”前臺(tái)任務(wù)”的本質(zhì)區(qū)別只有一個(gè):是否繼承標(biāo)準(zhǔn)輸入。
·啟動(dòng)時(shí)以后臺(tái)任務(wù)啟動(dòng),只需要在原來(lái)的命令后面加上&
,啟動(dòng)的進(jìn)程就會(huì)變?yōu)楹笈_(tái)進(jìn)程。
# root @ WeideMac-Pro in ~ [14:15:51] C:130
# 在后臺(tái)運(yùn)行一個(gè)Python
$ python &
[2] 12162
# root @ WeideMac-Pro in ~ [14:15:56]
$ Python3.6.1|Anaconda custom (x86_64)| (default, May112017, 13:04:09)
[GCC 4.2.1CompatibleApple LLVM 6.0(clang-600.0.57)] on darwin
Type'help', 'copyright', 'credits'or'license'for more information.
[2] + 12162 suspended (tty output) python
# root @ WeideMac-Pro in ~ [14:15:56]
# 這時(shí)候發(fā)現(xiàn)命令行可以繼續(xù)執(zhí)行其他命令了,使用fg命令,將最后一個(gè)后臺(tái)任務(wù)切換為前臺(tái)任務(wù)
$ fg
[2] - 12162 continued python
>>> print('Hello')
Hello
>>>
·將正在運(yùn)行的前臺(tái)任務(wù)切換為后臺(tái)任務(wù),先ctrl+z將前臺(tái)程序掛起, 然后執(zhí)行bg
命令繼續(xù)運(yùn)行。
# root @ WeideMac-Pro in ~ [14:20:10]
# 在前臺(tái)運(yùn)行一個(gè)Python
$ python
Python3.6.1|Anaconda custom (x86_64)| (default, May112017, 13:04:09)
[GCC 4.2.1CompatibleApple LLVM 6.0(clang-600.0.57)] on darwin
Type'help', 'copyright', 'credits'or'license'for more information.
>>> ^Z
[1] + 12248 suspended python
(base)
# root @ WeideMac-Pro in ~ [14:20:28] C:146
# bg命令,讓后臺(tái)任務(wù)繼續(xù)執(zhí)行
$ bg
[1] + 12248 continued python
[1] + 12248 suspended (tty output) python
將一個(gè)程序變?yōu)楹笈_(tái)任務(wù)并不能達(dá)到退出命令行后繼續(xù)運(yùn)行的效果,這是因?yàn)榍懊娴哪切┣芭_(tái)和后臺(tái)進(jìn)程都算做是我們打開(kāi)那個(gè)命令行的子進(jìn)程,如果我們關(guān)掉了命令行,系統(tǒng)將向這些子進(jìn)程發(fā)送一個(gè)稱為“SIGHUP”的信號(hào),子進(jìn)程收到信號(hào)后就會(huì)關(guān)閉。因此,只需要讓子進(jìn)程忽略SIGHUP信號(hào),就能實(shí)現(xiàn)關(guān)閉命令行窗口后程序繼續(xù)運(yùn)行了。
nohup 全稱:no hang up(不掛起)??梢詫⒊绦蛞?strong>忽略掛起信號(hào)的方式運(yùn)行起來(lái),被運(yùn)行的程序的輸出信息將不會(huì)顯示到終端
nohup Command[ Arg… ] [ & ]
nohup Command [Arg...] [ &] 最后的' &':表示后臺(tái)運(yùn)行,不霸占交互命令行
如果不將 nohup 命令的輸出重定向,輸出將附加到當(dāng)前目錄的 nohup.out 文件中。
如果當(dāng)前目錄的 nohup.out 文件不可寫(xiě),輸出重定向到 $HOME/nohup.out 文件中。
如果沒(méi)有文件能創(chuàng)建或打開(kāi)以用于追加,那么 Command 參數(shù)指定的命令不可調(diào)用。
示例:
nohup jupyter notebook &
運(yùn)行上面的命令,就會(huì)以后臺(tái)任務(wù)運(yùn)行jupyter,并且忽略掛起信號(hào),即使關(guān)閉了命令行,我們依然可以正常訪問(wèn) jupyter notebook。
既然程序可以放在后臺(tái)運(yùn)行,那我們?cè)撊绾侮P(guān)掉后臺(tái)任務(wù)呢?要關(guān)閉后臺(tái)任務(wù),關(guān)鍵是要找到后臺(tái)任務(wù)的進(jìn)程ID, 然后通過(guò)kill -9 [id]
來(lái)殺死進(jìn)程。這里提供兩種方法:
·如果創(chuàng)建任務(wù)的終端窗口沒(méi)有被關(guān)掉,可以使用jobs -l
查看進(jìn)程ID
# root @ WeideMac-Pro in ~ [15:22:22]
$ python
Python3.6.1|Anaconda custom (x86_64)| (default, May112017, 13:04:09)
[GCC 4.2.1CompatibleApple LLVM 6.0(clang-600.0.57)] on darwin
Type'help', 'copyright', 'credits'or'license'for more information.
>>> ^Z
[1] + 13089 suspended python
# root @ WeideMac-Pro in ~ [15:22:34]
$ jobs -l
[1] + 13089 suspended python
# root @ WeideMac-Pro in ~ [15:22:47]
$ kill -913089
[1] + 13089 killed python
·如果命令行被關(guān)掉了,我們jobs
命令是找不到我們的后臺(tái)任務(wù)的,因?yàn)槊總€(gè)后臺(tái)任務(wù)都是和命令行關(guān)聯(lián)在一起,這里我們可以使用ps命令:
# root @ WeideMac-Pro in ~ [15:33:30]
$ python &
[1] 13434
# root @ WeideMac-Pro in ~ [15:33:39]
$ Python 3.6.1 |Anaconda custom (x86_64)| (default, May 11 2017, 13:04:09)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type 'help', 'copyright', 'credits' or 'license' for more information.
[1] + 13434 suspended (tty output) python
# root @ WeideMac-Pro in ~ [15:33:39]
$ ps -ef|grep python|grep -v grep
501 13434 12860 0 3:33下午 ttys000 0:00.04 python
# root @ WeideMac-Pro in ~ [15:33:42]
$ kill -9 13434
[1] + 13434 killed python
聯(lián)系客服