linux下 > /dev/null 2 > &1 的意思和如何在后台啟動進程


一、幾個基本符號及其含義 

之前看到別人寫的一個shell腳本,有一個命令是:rm -f ${src_tmp_file} > /dev/null 2>&1

現在大概明白是什么意思了

當執行shell命令時,會默認打開3個文件,每個文件有對應的文件描述符來方便我們使用

類型 文件描述符 默認情況 對應文件句柄位置
標准輸入(standard input) 0 從鍵盤獲得輸入 /proc/self/fd/0
標准輸出(standard output) 1 輸出到屏幕(即控制台) /proc/self/fd/1
錯誤輸出(error output) 2 輸出到屏幕(即控制台) /proc/self/fd/2

 

  • /dev/null 表示空設備文件
  • 0 表示stdin標准輸入
  • 1 表示stdout標准輸出
  • 2 表示stderr標准錯誤

>/dev/null

這條命令的作用是將標准輸出1重定向到/dev/null中。 /dev/null代表linux的空設備文件,所有往這個文件里面寫入的內容都會丟失,俗稱“黑洞”。那么執行了>/dev/null之后,標准輸出就會不再存在,沒有任何地方能夠找到輸出的內容。

&1

對於 &1 更准確的說應該是文件描述符 1,而1標識標准輸出,stdout。

2

對於2 ,表示標准錯誤,stderr。

2>&1 的意思就是將標准錯誤重定向到標准輸出。這里標准輸出已經重定向到了 /dev/null。那么標准錯誤也會輸出到/dev/null

 

rm -f ${src_tmp_file} > /dev/null 2>&1 其實等於 rm -f ${src_tmp_file} 1 > /dev/null 2>&1

rm -f ${src_tmp_file} 1 > /dev/null 2>&1,可以看成三部分:
1.命令:rm -f ${src_tmp_file}
2. 1 > /dev/null:把這條刪除命令的標准輸出重定向到/dev/null(即不會顯示)
3. 2>&1:把錯誤輸出重定向到標准輸出,而上面把標准輸出重定向到/dev/null,即錯誤輸出也重定向到/dev/null
4. 因此這條命令無論正確執行還是錯誤,都不會有任何顯示

 

二、測試

ls 2 > a.txt:不會報沒有2文件的錯誤,但會輸出一個空的文件a.txt;

ls xxx 2 > a.txt:會報錯,沒有xxx這個文件,但是錯誤信息輸出到了文件a.txt中,不會顯示在終端;

ls xxx 2 > &1:錯誤跑到標准輸出了;

ls xxx > out.txt 2 > &1:等於 ls xxx 1 > out.txt 2 > &1;正確或者錯誤的信息都寫到out.txt,不會顯示在終端。

 

三、如何在后台啟動進程

1、進程的啟動方式

1.前台啟動:用戶輸入命令,直接執行程序
2.后台啟動:在命令行尾加入"&"符號,例如后台啟動weblogic服務:nohup ./startWeblogic.sh &

 

2、后台不掛斷運行進程

要想在后台不掛斷運行進程,即使把終端關閉了也能繼續運行的進程,單單使用"&"是不行的,
因為"&"只能讓進程在后台啟動,如果關閉終端,這個進程還是會結束的,因此需要配合"nohup"命令使用

命令使用
nohup command > /dev/null 2>&1 &


# 解釋
nohup:
no hangup,不掛斷地運行命令。只用nohup命令,關閉終端,進程還存在。若在終端中直接使用Ctrl+c,則會關閉進程。
若沒有指定標准輸出和標准錯誤,那么所有輸出都被重定向到一個名為nohup.out的文件中(比如:nohup command & )

在 Unix 的早期版本中,每個終端都會通過 modem 和系統通訊。當用戶 logout 時,modem 就會掛斷(hang up)電話。 同理,當 modem 斷開連接時,就會給終端發送 hangup 信號來通知其關閉所有子進程。

那么如果我們需要某個命令長時間運行,什么方法能最簡便的保證它在后台穩定運行呢?
我們知道,當用戶注銷(logout)或者網絡斷開時,終端會收到 HUP(hangup)信號從而關閉其所有子進程。
因此,我們的解決辦法就有兩種途徑:要么讓進程忽略 HUP 信號,要么讓進程運行在新的會話里從而成為不屬於此終端的子進程。  

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

2.setsid
nohup 無疑能通過忽略 HUP 信號來使我們的進程避免中途被中斷,但如果我們換個角度思考,如果我們的進程不屬於接受 HUP 信號的終端的子進程,那么自然也就不會受到 HUP 信號的影響了。

在linux下,一個session是由一組進程組構成的,每個進程組又由多個進程構成。

# session創建
session可以在任何時候創建,調用setsid函數即可,session中的第一個進程即為這個session的leader,leader是不能變的。常見的創建session的場景是:
用戶登錄后,啟動bash進程時將會創建新的session,bash進程會作為session的leader,隨后bash里面運行的進程(不特殊處理)都將屬於這個session。

# 特點
session的主要特點是當session的leader退出后,session中的所有其它進程將會收到SIGHUP信號,其默認行為是終止進程,即session的leader退出后,session中的其它進程也會退出。
如果session和tty關聯的話,它們之間只能一一對應,一個tty只能屬於一個session,一個session只能打開一個tty。當然session也可以不和任何tty關聯。

# 使用
只需要在命令使用前加上setsid就可以了,該方法的作用是新建一個新的session,使用戶進程和bash不在同一個session,並使自己成為leader。
hangup名稱的來由

 

command:
command是用戶輸入的命令,可自行設置。如“java -jar crm.jar”等。

 

&:
后台運行。當你只使用“&”時,關閉終端,進程會關閉。

建議:
所以當你要讓程序在后台不掛斷運行時,需要將nohup和&一起使用。

例如:nohup ./startWeblogic.sh > /dev/null 2>&1 &

 

3、tips

jobs:
使用"jobs"可查看當前有多少在后台運行的命令。

fg:
將后台中的命令調至前台繼續運行。如果后台中有多個命令,可以用"fg %jobnumber"(是jobs編號,不是進程號)將選中的命令調出。

bg:
將一個在后台暫停的命令,變成在后台繼續執行。如果后台中有多個命令,可以用"bg %jobnumber"將選中的命令調出。

kill %jobnumber: 終止后台進程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM