Linux 標準輸出(stdout)和標準錯誤(stderr)的重定向

之前常常會聽到這些詞,還有標準輸入之類,徹底不明因此。直到最近須要讓python腳本里的print內容打印到日誌文件裏,纔開始研究這究竟是什麼。

原來,標準輸出(stdout)指的就是在命令行裏,每次你輸入指令後,終端上打印出來的那些話,那些反饋。標準錯誤(stderr)跟標準輸出差很少,只不過是程序出錯時反饋的內容。標準輸入(stdin)就是程序指示讓你輸入用戶名密碼之類的這種,這裏很少談輸入。python

問題是,咱們很經常使用的會讓一些腳本本身在後臺24/7運行,這種時候腳本的輸出內容到屏幕上(標準輸出)也沒什麼意義,咱們看不到也保存不了。因此最好讓它把反饋的內容所有直接寫如一個文件裏,咱們叫日誌文件,其實就是個txt。而後咱們本身能夠查看日誌來看到底發生了什麼。linux

這種把顯示到屏幕的程序反饋,變成存到文件裏的動做,咱們叫作輸出重定向(stdout redirection)

在命令行裏,咱們能夠用符號直接把程序輸出轉向到某個文件或某個程序,以下:git

$ git push > log.txt

而後,理論上咱們日常git push後的反饋就會保存到log.txt這個文件裏了,且屏幕上不會顯示任何東西。
但其實這個仍是有問題的,由於過後咱們發現有一些存到了log.txt,還有一些話漏網顯示到了屏幕上,沒存進去文檔裏。
其實原來這些顯示到屏幕上的反饋有些是stdout有些是stderr,咱們用>>>符號重定向,只是默認重定向stdout,沒有重定向stderr,因此會有漏網之魚。對此,咱們須要瞭解下這個符號的設定,和怎麼把stderr也包括進來,一塊兒重定向過去。shell

重定向符號和語句

稍微會一點點linux命令的,都會用到cmd > file這樣的語句,把命令反饋的輸出到一個文件裏。固然還有cmd >> file,這是把內容追加到文件裏,而不是從新擦寫一遍。>這個符號能夠念redirect to
實際上,重定向有不少種設置和配合,讓你能夠分別重定向標準輸出和標準錯誤,或者一塊兒重定向,而後還能夠選擇是隻輸出到文件裏仍是同時輸出大顯示屏上和文件裏。
這裏咱們就要了解一下設置重定向的基本語法了,以下:ubuntu

  • > 以擦寫的模式重定向至...
  • >> 以追加的模式重定向至...
  • 1 表明stdout標準輸出
  • 2 表明stderr標準錯誤

因此,cmd > file其實是縮略了的寫法,理解起來,應該是cmd &1> file,也就是隻把標準輸出轉出去。
那麼同理,只把標準錯誤轉出去,就應該是cmd &2> file
其中,&符號沒任何實際意義,只是以致區分,表明後面的符號是要設置重定向用的,而不是某個文件的名字。app

2>&1

每次查重定向問題時,咱們總會看到這句話,通常人很難理解這究竟是在幹嗎。我一開始覺得是2要大於1什麼的,真是笑話。
其實這是個重定向的設置,設置讓2重定向到1,也就是讓stderr標準錯誤重定向到stdout標準輸出,而後兩個並在一塊兒再重定向。其中&沒什麼意思只是區分開來1是表明stdout而不是表明一個文件名。
用起來的格式是:cmd > file 2>&1
爲何設置要放在後面呢?
具體暫時還不知道,只知道是這麼用,放在前面還不行只能放在後面。this

好比:spa

$ git push > log.txt 2>&1

那麼這時候,屏幕上就真的不會顯示任何東西了,標準輸出、標準錯誤,所有都會存到log.txt文件裏了。命令行

經常使用重定向及解釋

參考文章:stackoverflow回答

image

  • command > output.txt

The standard output stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, it gets overwritten.日誌

  • command >> output.txt

The standard output stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

  • command 2> output.txt

The standard error stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, it gets overwritten.

  • command 2>> output.txt

The standard error stream will be redirected to the file only, it will not be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

  • command &> output.txt

Both the standard output and standard error stream will be redirected to the file only, nothing will be visible in the terminal. If the file already exists, it gets overwritten.

  • command &>> output.txt

Both the standard output and standard error stream will be redirected to the file only, nothing will be visible in the terminal. If the file already exists, the new data will get appended to the end of the file..

  • command | tee output.txt

The standard output stream will be copied to the file, it will still be visible in the terminal. If the file already exists, it gets overwritten.

  • command | tee -a output.txt

The standard output stream will be copied to the file, it will still be visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

  • (*)

Bash has no shorthand syntax that allows piping only StdErr to a second command, which would be needed here in combination with tee again to complete the table. If you really need something like that, please look at "How to pipe stderr, and not stdout?" on Stack Overflow for some ways how this can be done e.g. by swapping streams or using process substitution.

  • command |& tee output.txt

Both the standard output and standard error streams will be copied to the file while still being visible in the terminal. If the file already exists, it gets overwritten.

  • command |& tee -a output.txt

Both the standard output and standard error streams will be copied to the file while still being visible in the terminal. If the file already exists, the new data will get appended to the end of the file.

相關文章
相關標籤/搜索