shell中可能經常能看到:>/dev/null 2>&1
命令的結果可以通過%>的形式來定義輸出
/dev/null 代表空設備文件
> 代表重定向到哪里,例如:echo "123" > /home/123.txt
1 表示stdout標準輸出,系統默認值是1,所以">/dev/null"等同于"1>/dev/null"
2 表示stderr標準錯誤
& 表示等同于的意思,2>&1,表示2的輸出重定向等同于1
那么本文標題的語句:
1>/dev/null 首先表示標準輸出重定向到空設備文件,也就是不輸出任何信息到終端,說白了就是不顯示任何信息。
2>&1 接著,標準錯誤輸出重定向等同于 標準輸出,因為之前標準輸出已經重定向到了空設備文件,所以標準錯誤輸出也重定向到空設備文件。
A. 1> /dev/null 表示將命令的標準輸出重定向到 /dev/null2>/dev/null 表示將命令的錯誤輸出重定向到 /dev/null1 - denotes stdout ( standard output )2 - denotes stderr? ( standard error )/dev/null就相當與windows里的回收站,只是進去了不能再出來了。>/dev/null 就是將標準輸出和標準出錯的信息屏蔽不顯示
B.>/dev/null 2>&1?? also can write? as? 1>/dev/null 2>&1???? - stdout redirect to /dev/null (no stdout) ,and redirect stderr to stdout? (stderr gone as well) . end up it turns both stderr and stdout off
C.a little practice may help to undstand above .? #ls /usr? /nothing #ls /usr? /nothing? 2>/dev/null #ls /usr? /nothing? >/dev/null 2>&1
我們經常會在UNIX系統下的一些腳本中看到類似”2>&1″這樣的用法,例如“/path/to/prog 2>&1 > /dev/null &”,那么它的具體含義是什么呢?
UNIX有幾種輸入輸出流,它們分別與幾個數字有如下的對應關系:0-標準輸入流(stdin),1-標準輸出流(stdout),2-標準錯誤流 (stderr)。”2>&1″的意思就是將stderr重定向至stdout,并一起在屏幕上顯示出來。如果不加數字,那么默認的重定向動作是針對stdout(1)的,比如”ls -l > result”就等價于”ls -l 1 > result”。這樣便于我們更普遍性的理解重定向過程。
下面舉例說明:
#cat std.sh
#!/bin/sh
echo “stdout”
echo “stderr” >&2
#/bin/sh std.sh 2>&1 > /dev/null
stderr
#/bin/sh std.sh > /dev/null 2>&1
第一條命令的輸出結果是stderr,因為stdout和stderr合并后一同重定向到/dev/null,但stderr并未被清除,因此仍將在屏幕中顯示出來;第二條命令無輸出,因為當stdout重定向至/dev/null后,stderr又重定向到了stdout,這樣stderr也被輸出到了/dev/null。
今天在做例行工作的時候,發現機器上的sendmail進程奇多無比,并且機器IO好像也很慢。后來發現在/var/spool/clientmqueue目錄下ls幾乎要死人 – 最少有10萬個文件
ps|grep sendmail看這些sendmail進程里面都有/var/spool/clientmqueue
cd過去隨便打開了個文件看了下,發現是我crontab里面執行的程序的exception,估計是我的crontab每次執行,linux都試圖發郵件給crontab的用戶但是又沒有配sendmail,所以東西就都被扔到/var/spool/clientmqueue下面了。然后我才明白為啥以前別人寫的crontab要加上> /dev/null 2>&1,原來這樣就不會每次執行crontab都把結果或者excetion發郵件了。
把這10萬個文件刪掉后,一切恢復正常
問題現象:
linux操作系統中的/var/spool/clientmqueue/目錄下存在大量文件。
原因分析:系統中有用戶開啟了cron,而cron中執行的程序有輸出內容,輸出內容會以郵件形式發給cron的用戶,而sendmail沒有啟動所以就產生了這些文件;
解決辦法: 1、 將crontab里面的命令后面加上> /dev/null 2>&1
2、知識點:
2>:重定向錯誤。
2>&1:把錯誤重定向到輸出要送到的地方。即把上述命令的執行結果重定向到/dev/null,即拋棄,同時,把產生的錯誤也拋棄。
3、具體代碼:
(1)、# crontab -u cvsroot -l
01 01 * * * /opt/bak/backup
01 02 * * * /opt/bak/backup2
(2)、# vi /opt/bak/backup
#!/bin/sh
cd /
getfacl -R repository > /opt/bak/backup.acl
(3)、# vi /opt/bak/backup2
#!/bin/sh
week=`date +%w`
tar zcvfp /opt/bak/cvs$week/cvs.tar.gz /repository >/dev/null 2>&1
4、清除/var/spool/clientmqueue/目錄下的文件:
# cd /var/spool/clientmqueue
# rm -rf *
如果文件太多,占用空間太大,用上面命令刪除慢的話,就執行下面的命令:
# cd /var/spool/clientmqueue
# ls | xargs rm -f
在一個風和日麗的夜晚,我坐在家裡看著電視,後來手機一陣響起,結果是楊老師發現一臺主機發生異常,伺服器的 /var/spool/mqueue 目錄被塞了一堆還沒有寄出的信件,而當時沒有把 /var/spool 另外分割出來,所以也影響到了系統 root (/) 區塊,只剩六百多 MB 可以使用,這時一想會有幾個可能.
這臺 server 有幫學校的 PC 做寄送信件,所以可能是廣告信在寄出.
使用這臺 server 做 mail 寄信的機器,可能是中毒,於是就不斷的送信出去.
一開始只有想到這兩個原因,但是可要把被吞掉的空間給吐出來,所以就打算把所有的 mail queue 都先砍了,當然,要先停掉 mail service.
在砍這些正在排隊的信件時,發現一件事,就是裡面的檔案太多了,使用 ls 命令就變得超級遲頓,沒有反應,使用 mailq 來看看到底是那些信被 queue 住也沒辦法,後來想想算了,只好全剖砍了,不要再玩下去,之後,很順手的下了 rm -rf * 這下子呢,發生了一件很離奇的事,居然檔案太多無法刪除,第一次聽到 rm 在 complain (我是聽到的,楊老師是實作者,所以他有看到 ^^).
那個 error 是: bash: /bin/rm: Argument list too long
雖然無法刪除,但是楊兄並不放棄,到主機面前,開啟了 X Window 之後使用那 Linuxer 最常使用的鸚鵡螺 (nautilus) 開啟到 /var/spool/mqueue. 喔 ~ 可以使用 X Window 來刪呢 ! 後來想說即然 X Window 有這麼大的本事,那麼就用它來刪了其它的 queue files 就好啦,於是掛上電話,放楊兄一個人努力的在機房刪著 ...
當然我也沒有閒著,電視劇剛好演完,於是開啟我的工作伙伴,再度當網路潛水艇 ... 游著游著,突然想到,何不使用 find 來刪除看看 ? 於是刪回歷史文件,發現一個命令就是 find ./ | xargs rm -rf 千萬別小看這小小的指令,因為在我看完之後不久,楊兄打進來,說已經刪到手軟,這時也是晚上十點了,於是我就推薦了這個這道指令,嗯,很好,全都刪了,還頗快的 ...
喔,還沒說為什麼會刪到手軟,是因為 nautilus 在 Load 目錄時,是分批的,不是一次全部讀,所以一次大約是幾千封在讀,刪了之後,沒想到又冒出了還有幾千封 ... 真是嚇死人,後來推論應該是分批的關係.
在下了 find ./ | xargs rm -rf 之後,還在訝異快速之餘,就發現時間不多了,學校也要關門,所以就先 say bye bye,在現場苦命的楊兄也回家休息了.
分析:
rm 有最大一次刪除的數量,所以當一個目錄裡有太多的檔案或目錄時,就會出現錯誤,小弟試過應該是在二萬以下,而使用 find ./ | xargs rm -rf 的目的是先使用 find 列出檔案,再導向到 xargs,xargs 再喂給 rm,在這裡,xargs 會分批依照 rm 的最大數量餵給 rm,然後就可以順利刪除檔案了
。而真正的原因,有可能是 rm 的版本或是檔案系統的問題,我也不再繼續追就,反正能辦好事就好
下面提供當時小弟測試的一個小小 shell script
下載:
mk-file.sh
(這個 shell script 會有目錄下產生 20000 個檔案。)
接下來來做個小小測試:
root # mkfile.sh
root #
會產生 20000 個小檔案,名稱為 test-file-{1~19999}
直接使用 rm 去刪除:
root # rm -rf test-file-*
-bash: /bin/rm: Argument list too long (會回應引數過長的訊息)
改搭配 find 來刪除
root # find ./ -iname 'test-file-*' | xargs rm -rf
root # ls
mk-file.sh
root #
這樣就順利被刪除了。
---------------------------------
#tool_action
45 4 * * * /bin/sh /data/stat/crontab/exec_tool_action_analysis_db.sh >> /data/stat/logs/exec_tool_action_analysis_db.sh.log > /dev/null 2>&1
45 5 * * * /bin/sh /data/stat/crontab/exec_tool_action_analysis_user.sh >> /data/stat/logs/exec_tool_action_analysis_user.sh.log > /dev/null 2>&1
否則在/var/spool/clientmqueue 下會產生以下文件:
-rw-rw---- 1 smmsp?? smmsp? 975 Jan 17 10:50 qfq0H2o4ei031197
----------------------------------------------------------
#
40 3 * * * sh /work/yule/shell/export_anchor_multi_4_mysql.sh > /work/yule/logs/export_anchor_multi_4_mysql.log 2>&1
命令的結果可以通過%>的形式來定義輸出
/dev/null 代表空設備文件
> 代表重定向到哪里,例如:echo "123" > /home/123.txt
1 表示stdout標準輸出,系統默認值是1,所以">/dev/null"等同于"1>/dev/null"
2 表示stderr標準錯誤
& 表示等同于的意思,2>&1,表示2的輸出重定向等同于1
那么本文標題的語句:
1>/dev/null 首先表示標準輸出重定向到空設備文件,也就是不輸出任何信息到終端,說白了就是不顯示任何信息。
2>&1 接著,標準錯誤輸出重定向等同于 標準輸出,因為之前標準輸出已經重定向到了空設備文件,所以標準錯誤輸出也重定向到空設備文件。
A. 1> /dev/null 表示將命令的標準輸出重定向到 /dev/null2>/dev/null 表示將命令的錯誤輸出重定向到 /dev/null1 - denotes stdout ( standard output )2 - denotes stderr? ( standard error )/dev/null就相當與windows里的回收站,只是進去了不能再出來了。>/dev/null 就是將標準輸出和標準出錯的信息屏蔽不顯示
B.>/dev/null 2>&1?? also can write? as? 1>/dev/null 2>&1???? - stdout redirect to /dev/null (no stdout) ,and redirect stderr to stdout? (stderr gone as well) . end up it turns both stderr and stdout off
C.a little practice may help to undstand above .? #ls /usr? /nothing #ls /usr? /nothing? 2>/dev/null #ls /usr? /nothing? >/dev/null 2>&1
我們經常會在UNIX系統下的一些腳本中看到類似”2>&1″這樣的用法,例如“/path/to/prog 2>&1 > /dev/null &”,那么它的具體含義是什么呢?
UNIX有幾種輸入輸出流,它們分別與幾個數字有如下的對應關系:0-標準輸入流(stdin),1-標準輸出流(stdout),2-標準錯誤流 (stderr)。”2>&1″的意思就是將stderr重定向至stdout,并一起在屏幕上顯示出來。如果不加數字,那么默認的重定向動作是針對stdout(1)的,比如”ls -l > result”就等價于”ls -l 1 > result”。這樣便于我們更普遍性的理解重定向過程。
下面舉例說明:
#cat std.sh
#!/bin/sh
echo “stdout”
echo “stderr” >&2
#/bin/sh std.sh 2>&1 > /dev/null
stderr
#/bin/sh std.sh > /dev/null 2>&1
第一條命令的輸出結果是stderr,因為stdout和stderr合并后一同重定向到/dev/null,但stderr并未被清除,因此仍將在屏幕中顯示出來;第二條命令無輸出,因為當stdout重定向至/dev/null后,stderr又重定向到了stdout,這樣stderr也被輸出到了/dev/null。
今天在做例行工作的時候,發現機器上的sendmail進程奇多無比,并且機器IO好像也很慢。后來發現在/var/spool/clientmqueue目錄下ls幾乎要死人 – 最少有10萬個文件
ps|grep sendmail看這些sendmail進程里面都有/var/spool/clientmqueue
cd過去隨便打開了個文件看了下,發現是我crontab里面執行的程序的exception,估計是我的crontab每次執行,linux都試圖發郵件給crontab的用戶但是又沒有配sendmail,所以東西就都被扔到/var/spool/clientmqueue下面了。然后我才明白為啥以前別人寫的crontab要加上> /dev/null 2>&1,原來這樣就不會每次執行crontab都把結果或者excetion發郵件了。
把這10萬個文件刪掉后,一切恢復正常
問題現象:
linux操作系統中的/var/spool/clientmqueue/目錄下存在大量文件。
原因分析:系統中有用戶開啟了cron,而cron中執行的程序有輸出內容,輸出內容會以郵件形式發給cron的用戶,而sendmail沒有啟動所以就產生了這些文件;
解決辦法: 1、 將crontab里面的命令后面加上> /dev/null 2>&1
2、知識點:
2>:重定向錯誤。
2>&1:把錯誤重定向到輸出要送到的地方。即把上述命令的執行結果重定向到/dev/null,即拋棄,同時,把產生的錯誤也拋棄。
3、具體代碼:
(1)、# crontab -u cvsroot -l
01 01 * * * /opt/bak/backup
01 02 * * * /opt/bak/backup2
(2)、# vi /opt/bak/backup
#!/bin/sh
cd /
getfacl -R repository > /opt/bak/backup.acl
(3)、# vi /opt/bak/backup2
#!/bin/sh
week=`date +%w`
tar zcvfp /opt/bak/cvs$week/cvs.tar.gz /repository >/dev/null 2>&1
4、清除/var/spool/clientmqueue/目錄下的文件:
# cd /var/spool/clientmqueue
# rm -rf *
如果文件太多,占用空間太大,用上面命令刪除慢的話,就執行下面的命令:
# cd /var/spool/clientmqueue
# ls | xargs rm -f
在一個風和日麗的夜晚,我坐在家裡看著電視,後來手機一陣響起,結果是楊老師發現一臺主機發生異常,伺服器的 /var/spool/mqueue 目錄被塞了一堆還沒有寄出的信件,而當時沒有把 /var/spool 另外分割出來,所以也影響到了系統 root (/) 區塊,只剩六百多 MB 可以使用,這時一想會有幾個可能.
這臺 server 有幫學校的 PC 做寄送信件,所以可能是廣告信在寄出.
使用這臺 server 做 mail 寄信的機器,可能是中毒,於是就不斷的送信出去.
一開始只有想到這兩個原因,但是可要把被吞掉的空間給吐出來,所以就打算把所有的 mail queue 都先砍了,當然,要先停掉 mail service.
在砍這些正在排隊的信件時,發現一件事,就是裡面的檔案太多了,使用 ls 命令就變得超級遲頓,沒有反應,使用 mailq 來看看到底是那些信被 queue 住也沒辦法,後來想想算了,只好全剖砍了,不要再玩下去,之後,很順手的下了 rm -rf * 這下子呢,發生了一件很離奇的事,居然檔案太多無法刪除,第一次聽到 rm 在 complain (我是聽到的,楊老師是實作者,所以他有看到 ^^).
那個 error 是: bash: /bin/rm: Argument list too long
雖然無法刪除,但是楊兄並不放棄,到主機面前,開啟了 X Window 之後使用那 Linuxer 最常使用的鸚鵡螺 (nautilus) 開啟到 /var/spool/mqueue. 喔 ~ 可以使用 X Window 來刪呢 ! 後來想說即然 X Window 有這麼大的本事,那麼就用它來刪了其它的 queue files 就好啦,於是掛上電話,放楊兄一個人努力的在機房刪著 ...
當然我也沒有閒著,電視劇剛好演完,於是開啟我的工作伙伴,再度當網路潛水艇 ... 游著游著,突然想到,何不使用 find 來刪除看看 ? 於是刪回歷史文件,發現一個命令就是 find ./ | xargs rm -rf 千萬別小看這小小的指令,因為在我看完之後不久,楊兄打進來,說已經刪到手軟,這時也是晚上十點了,於是我就推薦了這個這道指令,嗯,很好,全都刪了,還頗快的 ...
喔,還沒說為什麼會刪到手軟,是因為 nautilus 在 Load 目錄時,是分批的,不是一次全部讀,所以一次大約是幾千封在讀,刪了之後,沒想到又冒出了還有幾千封 ... 真是嚇死人,後來推論應該是分批的關係.
在下了 find ./ | xargs rm -rf 之後,還在訝異快速之餘,就發現時間不多了,學校也要關門,所以就先 say bye bye,在現場苦命的楊兄也回家休息了.
分析:
rm 有最大一次刪除的數量,所以當一個目錄裡有太多的檔案或目錄時,就會出現錯誤,小弟試過應該是在二萬以下,而使用 find ./ | xargs rm -rf 的目的是先使用 find 列出檔案,再導向到 xargs,xargs 再喂給 rm,在這裡,xargs 會分批依照 rm 的最大數量餵給 rm,然後就可以順利刪除檔案了
。而真正的原因,有可能是 rm 的版本或是檔案系統的問題,我也不再繼續追就,反正能辦好事就好

下面提供當時小弟測試的一個小小 shell script
下載:
mk-file.sh
(這個 shell script 會有目錄下產生 20000 個檔案。)
接下來來做個小小測試:
root # mkfile.sh
root #
會產生 20000 個小檔案,名稱為 test-file-{1~19999}
直接使用 rm 去刪除:
root # rm -rf test-file-*
-bash: /bin/rm: Argument list too long (會回應引數過長的訊息)
改搭配 find 來刪除
root # find ./ -iname 'test-file-*' | xargs rm -rf
root # ls
mk-file.sh
root #
這樣就順利被刪除了。
---------------------------------
#tool_action
45 4 * * * /bin/sh /data/stat/crontab/exec_tool_action_analysis_db.sh >> /data/stat/logs/exec_tool_action_analysis_db.sh.log > /dev/null 2>&1
45 5 * * * /bin/sh /data/stat/crontab/exec_tool_action_analysis_user.sh >> /data/stat/logs/exec_tool_action_analysis_user.sh.log > /dev/null 2>&1
否則在/var/spool/clientmqueue 下會產生以下文件:
-rw-rw---- 1 smmsp?? smmsp? 975 Jan 17 10:50 qfq0H2o4ei031197
----------------------------------------------------------
#
40 3 * * * sh /work/yule/shell/export_anchor_multi_4_mysql.sh > /work/yule/logs/export_anchor_multi_4_mysql.log 2>&1
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
