[Linux] Linux指令懶人包:nohup、&、Redirecting Output等常用指令

Cancerpio
May 14, 2023

--

最近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 &

--

--