以前經(jīng)常會(huì)聽(tīng)到這些詞闲昭,還有標(biāo)準(zhǔn)輸入之類,完全不明所以域滥。直到最近需要讓python腳本里的print內(nèi)容打印到日志文件里纵柿,才開(kāi)始研究這到底是什么。
原來(lái)启绰,標(biāo)準(zhǔn)輸出(stdout)
指的就是在命令行里昂儒,每次你輸入指令后,終端上打印出來(lái)的那些話委可,那些反饋渊跋。標(biāo)準(zhǔn)錯(cuò)誤(stderr)
跟標(biāo)準(zhǔn)輸出差不多,只不過(guò)是程序出錯(cuò)時(shí)反饋的內(nèi)容着倾。標(biāo)準(zhǔn)輸入(stdin)
就是程序指示讓你輸入用戶名密碼之類的這種拾酝,這里不多談?shì)斎搿?/p>
問(wèn)題是,我們很常用的會(huì)讓一些腳本自己在后臺(tái)24/7運(yùn)行卡者,這種時(shí)候腳本的輸出內(nèi)容到屏幕上(標(biāo)準(zhǔn)輸出)也沒(méi)什么意義蒿囤,我們看不到也保存不了。所以最好讓它把反饋的內(nèi)容全部直接寫如一個(gè)文件里虎眨,我們叫日志文件蟋软,其實(shí)就是個(gè)txt。然后我們自己可以查看日志來(lái)看到底發(fā)生了什么嗽桩。
這種把顯示到屏幕的程序反饋岳守,變成存到文件里的動(dòng)作,我們叫做輸出重定向(stdout redirection)
在命令行里碌冶,我們可以用符號(hào)直接把程序輸出轉(zhuǎn)向
到某個(gè)文件或某個(gè)程序湿痢,如下:
$ git push > log.txt
然后,理論上我們平常git push
后的反饋就會(huì)保存到log.txt
這個(gè)文件里了扑庞,且屏幕上不會(huì)顯示任何東西譬重。
但其實(shí)這個(gè)還是有問(wèn)題的,因?yàn)槭潞笪覀儼l(fā)現(xiàn)有一些存到了log.txt罐氨,還有一些話漏網(wǎng)顯示到了屏幕上臀规,沒(méi)存進(jìn)去文檔里。
其實(shí)原來(lái)這些顯示到屏幕上的反饋有些是stdout
有些是stderr
栅隐,我們用>
或>>
符號(hào)重定向塔嬉,只是默認(rèn)重定向stdout
玩徊,沒(méi)有重定向stderr
,所以會(huì)有漏網(wǎng)之魚(yú)谨究。對(duì)此恩袱,我們需要了解下這個(gè)符號(hào)的設(shè)定,和怎么把stderr
也包括進(jìn)來(lái)胶哲,一起重定向過(guò)去畔塔。
重定向符號(hào)和語(yǔ)句
稍微會(huì)一點(diǎn)點(diǎn)linux命令的,都會(huì)用到cmd > file
這樣的語(yǔ)句鸯屿,把命令反饋的輸出到一個(gè)文件里澈吨。當(dāng)然還有cmd >> file
,這是把內(nèi)容追加到文件里碾盟,而不是重新擦寫一遍棚辽。>
這個(gè)符號(hào)可以念redirect to
技竟。
實(shí)際上冰肴,重定向有很多種設(shè)置和配合,讓你可以分別重定向標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤榔组,或者一起重定向熙尉,然后還可以選擇是只輸出到文件里還是同時(shí)輸出大顯示屏上和文件里。
這里我們就要了解一下設(shè)置重定向的基本語(yǔ)法了搓扯,如下:
-
>
以擦寫的模式重定向至... -
>>
以追加的模式重定向至... -
1
代表stdout
標(biāo)準(zhǔn)輸出 -
2
代表stderr
標(biāo)準(zhǔn)錯(cuò)誤
所以检痰,cmd > file
實(shí)際上是縮略了的寫法,理解起來(lái)锨推,應(yīng)該是cmd &1> file
铅歼,也就是只把標(biāo)準(zhǔn)輸出轉(zhuǎn)出去。
那么同理换可,只把標(biāo)準(zhǔn)錯(cuò)誤轉(zhuǎn)出去椎椰,就應(yīng)該是cmd &2> file
。
其中沾鳄,&
符號(hào)沒(méi)任何實(shí)際意義慨飘,只是以至區(qū)分,代表后面的符號(hào)是要設(shè)置重定向用的译荞,而不是某個(gè)文件的名字瓤的。
2>&1
每次查重定向問(wèn)題時(shí),我們總會(huì)看到這句話吞歼,一般人很難理解這到底是在干嘛圈膏。我一開(kāi)始以為是2要大于1什么的,真是笑話篙骡。
其實(shí)這是個(gè)重定向的設(shè)置稽坤,設(shè)置讓2重定向到1桥帆,也就是讓stderr
標(biāo)準(zhǔn)錯(cuò)誤重定向到stdout
標(biāo)準(zhǔn)輸出,然后兩個(gè)并在一起再重定向慎皱。其中&
沒(méi)什么意思只是區(qū)分開(kāi)來(lái)1是代表stdout
而不是代表一個(gè)文件名老虫。
用起來(lái)的格式是:cmd > file 2>&1
。
為什么設(shè)置要放在后面呢?
具體暫時(shí)還不知道茫多,只知道是這么用祈匙,放在前面還不行只能放在后面。
比如:
$ git push > log.txt 2>&1
那么這時(shí)候天揖,屏幕上就真的不會(huì)顯示任何東西了夺欲,標(biāo)準(zhǔn)輸出、標(biāo)準(zhǔn)錯(cuò)誤今膊,全部都會(huì)存到log.txt文件里了些阅。
1>&2
這個(gè)是比較好用的方法:即程序輸出到屏幕,也輸出到文件斑唬。
常用重定向及解釋
參考文章:stackoverflow回答
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.