最近side project終於有點進展,也意味著一些能動且不會毀了一切的程式得以被部署到AWS。
這次部署的是Spring boot程式,是個需要一直執行監聽任務的kafka Consumer。
由於還沒被包裝成Docker容器,所以必須要處理背景執行的工作,使得程式在登出terminal後繼續執行。
處理背景執行並不困難,但每次遇到都要再重新回憶一次實在非常煩瑣,所以做個筆記,順便釐清一些以前沒看仔細的觀念。
Linux的背景執行
本文將介紹如何使用nohup、&、Redirecting Output等常用指令來實現在背景或後台執行程式,以及如何重定向輸出。
使用 ampersand (&) 讓程式在背景執行
$ command &
- 在執行command後面加上&,即可讓程式在背景執行。
- 但是當Linux送出SIGHUP訊號時,程式就會終止。
- 一般來說,當退出terminal時,Linux就會送出SIGHUP訊號,而使用nohup可以避免這個情況。
避免程式因為SIGHUP訊號而中止: 使用nohup
$ nohup command &
- 指令: nohup 執行的command &
為何nohup後面還要加上&
- nohup只是把SIGHUP訊號攔截並且避免程式因此而中止
- 要讓程式在背景執行還是需要在後面加上&
- 如果你要讓程式在背景執行,無論如何後面都要加上&。如果要進一步避免SIGHUP造成程式終止,則前面要再加上nohup
Linux定義的三個標準的資料流 : stdin, stdout, stderr
在Linux系統中,定義了三個標準的資料流,分別是stdin、stdout和stderr。
- stdin(編號0) 代表輸入的資料流,預設指的是從鍵盤輸入的資料
- stdout(編號1) 代表輸出的資料流,通常代表程式的一般log),預設為把資料輸出到螢幕
- stderr(編號 2) 代表輸出的錯誤資料流,通常代表程式的Error log,預設為把資料輸出到螢幕
/dev/null
- 又稱空裝置, 黑洞,可用來丟棄不需要的輸出流
- 在Linux系統中是一個特殊的裝置檔案,它丟棄一切寫入其中的資料,但會回報成功而不會出現錯誤。
常用的資料流Redirecting Output符號: >, &>
可以使用這些符號把程式的一般/Error log輸出到檔案
編號> 檔名: 把某編號的資料流輸出到檔案
- 不給編號的話,預設是1>,也就是把stdout 輸出
執行command > file.out //把log輸出到file.out
執行command > file.out // 把錯誤訊息輸出到file.out
&>檔名: 把stdout和stderr通通輸出到檔案
- &後面接編號代表某資料流, Ex: $1代表stdout
- &後面不接編號代表所有資料流
2>&1 : 把stderr輸出到stdout輸出的檔案
- $1 = stdout
- 2> 代表輸出到檔案
- 所以 2> $1 代表把stdout輸出到stdout輸出的檔案
>>
和>的用途都是輸出,但>會取代原本檔案內容, >>則是用append的方式從檔案結尾把資料寫入
合併nohup和Redirecting Output
上面幾個指令比較抽象 ,以下舉兩個執行java程式的例子:
使用nohup讓程式在背景/後台執行,並且指定一般log /error log輸出到output.log
nohup java -jar xxx.jar >out.file 2>&1 &
使用nohup讓程式在背景/後台執行,並且讓一般log /error log都丟棄 (不輸出到任何地方)
- 先把stdout (1) 輸出到 /dev/null, 再讓 stderr 輸出到stdout輸出的檔案
nohup java -jar xxx.jar > /dev/null 2>&1 &