Charpter 3
這一章我覺得大家是可以好好看看的扎运,這里面作者提到了一些我們有時候不太注意的概念:
- streams
- redirection
- pipes
- working with running programs
- command substitution
Working with Streams and Redirection
Working with Streams and Redirection Unix利用stream(流)這種文本處理哲學(xué)對于生信是非常有用的液茎,它允許我們處理數(shù)據(jù)之間的流牌柄,而非將數(shù)據(jù)一股腦地保存在內(nèi)存里面譬猫。 想象一下,如果你想要整合兩個超大的文件在一起谱仪,正常操作是会涎,打開一個大文件,復(fù)制舒帮,然后打開另一個大文件会喝,粘貼到另一個大文件里面。這里的每一步都會耗費(fèi)很大的內(nèi)存玩郊。但Unix則會將整合的兩個大文件的內(nèi)容打印到 standard output stream(標(biāo)準(zhǔn)輸出流)肢执,然后我們可以從終端重定向標(biāo)準(zhǔn)輸出流到我們想要的文件。
-
Redirecting Standard Error 標(biāo)準(zhǔn)錯誤流是用來輸出errors, warnings, and messages meant to be read by the user译红。
默認(rèn)情況下预茄,標(biāo)準(zhǔn)輸出流和標(biāo)準(zhǔn)錯誤流如果沒有重定向的話,都是輸出到終端上的。但也可以輸出到文件耻陕。
$ ls -l tb1.fasta leafy1.fasta ls: leafy1.fasta: No such file or directory -rw-r--r-- 1 vinceb staff 0 Feb 21 21:58 tb1.fasta $ ls -l tb1.fasta leafy1.fasta > listing.txt 2> listing.stderr $ cat listing.txt -rw-r--r-- 1 vinceb staff 152 Jan 20 21:24 tb1.fasta $ cat listing.stderr ls: leafy1.fasta: No such file or directory $ ls -l tb1.fasta leafy1.fasta > listing.txt 2>&1
有時候拙徽,我們并不想輸出報錯信息,或者輸出物理儲存里可能會拖慢程序的速度诗宣,這時候Unix操作系統(tǒng)就為我們提供了一個虛假的儲存(pseudodevice):/dev/null 膘怕。凡是寫到/dev/null里的都會消失。
tail有一個騷操作是tail -f召庞。設(shè)想一下你把標(biāo)準(zhǔn)錯誤流寫到了stderr.txt文件里面岛心,你可能會用tail時不時地看下,看有什么報錯信息篮灼。但用了tail -f忘古,你就可以持續(xù)地監(jiān)控這個文件了。
-
Using Standard Input Redirection Unix也提供一種叫標(biāo)準(zhǔn)輸入流(standard input )的重定向操作诅诱。通常情況下髓堪,標(biāo)準(zhǔn)輸入流是來自于你的鍵盤。但是用 < 這個重定向操作符娘荡,我們也可以直接從一個文件里面讀取標(biāo)準(zhǔn)輸入流旦袋。
# 從inputfile輸入標(biāo)準(zhǔn)輸入流,然后標(biāo)準(zhǔn)輸出流到outputfile $ program < inputfile > outputfile
事實(shí)上它改,許多程序也可以直接用file參數(shù)來讀取文件,而不通過標(biāo)準(zhǔn)輸入流商乎。有些程序(生信里面很多)則會用 - 這個符號來表示他們應(yīng)該用標(biāo)準(zhǔn)輸入流央拖。
The Almighty Unix Pipe: Speed and Beauty in One 管道跟我們上面提到的重定向很像,但其不是重定向一個程序的結(jié)果到一個文件鹉戚,而是把程序的結(jié)果重定向成另一個程序的標(biāo)準(zhǔn)輸入鲜戒。但標(biāo)準(zhǔn)錯誤還是定向到你的終端屏幕上。
管道可以連接grep抹凳,cat等一系列程序遏餐。還可以連接其他語言的輸入和輸出。
-
Combining Pipes and Redirection 假如progarm 1是對input.txt 執(zhí)行操作赢底,然后輸出結(jié)果到標(biāo)準(zhǔn)輸出流失都,輸出診斷結(jié)果到標(biāo)準(zhǔn)錯誤流。而program 2則是接受program 1的輸出作為輸入幸冻,然后也輸出診斷結(jié)果到標(biāo)準(zhǔn)錯誤流粹庞。這時候,如果我們還是按正常操作洽损,program 1和2的診斷結(jié)果就會在屏幕上混淆庞溜。但我們可以這樣
program1 input.txt 2> program1.stderr | \ program2 2> program2.stderr > results.txt
-
因?yàn)楣艿乐荒苓B接標(biāo)準(zhǔn)輸出流。但如果我們想同時在結(jié)果里面看到標(biāo)準(zhǔn)輸出流和標(biāo)準(zhǔn)錯誤流的信息碑定。那么就可以把標(biāo)準(zhǔn)錯誤流重定向到標(biāo)準(zhǔn)輸出流那里流码。
# 2>&1 操作就是把標(biāo)準(zhǔn)錯誤流重定向到標(biāo)準(zhǔn)輸出流 $ program1 2>&1 | grep "error"
-
Even More Redirection: A tee in Your Pipe 另一個騷操作:儲存中間文件又官。
# 用了tee操作,既可以把program1的標(biāo)準(zhǔn)輸出流儲存成中間文件漫试,也可以輸出給program2 $ program1 input.txt | tee intermediate-file.txt | program2 > results.txt
Managing and Interacting with Processes
這里提到了
- running and managing processes in the background
- killing errant processes
- checking process exit status
-
當(dāng)我們在shell里面開始運(yùn)行命令之后六敬,我們是不能再對shell進(jìn)行操作的。短的命令還好商虐,長的命令就非常地蛋疼了觉阅。這時候我們就可以在運(yùn)行命令時候加入 &,來讓其在后臺運(yùn)行秘车。
# 這里的26577是proces ID或者說PID(進(jìn)程ID) $ program1 input.txt > results.txt & [1] 26577 # 這里的1是jobs IDs $ jobs [1]+ Running program1 input.txt > results.txt
-
為了把后臺運(yùn)行的命令帶到前臺來典勇,就可以用fg(for foreground)命令。當(dāng)你的后臺有許多的命令的時候叮趴,fg %<num>就可以選擇把對應(yīng)的進(jìn)程帶到前臺來割笙。
<num>就是所謂的jobs ID。
當(dāng)你的后臺進(jìn)程只有一個的時候眯亦,fg和fg %1是等效的伤溉。
關(guān)閉我們的終端,會發(fā)送一個Hangup signal(SIGHUP)信號給由已關(guān)閉終端之前開啟的所有進(jìn)程妻率。然后那些進(jìn)程受到這些信號之后乱顾,幾乎都會立刻停止運(yùn)行。
-
也可以把前臺運(yùn)行的放到后臺去宫静。這時候你需要先用ctrl+z發(fā)送掛起信號(suspend)走净,程序就會暫停。然后再用bg %<num>放到后臺孤里。
$ program1 input.txt > results.txt # forgot to append ampersand $ # enter control-z [1]+ Stopped program1 input.txt > results.txt $ bg [1]+ program1 input.txt > results.txt
殺進(jìn)程這部分詳細(xì)內(nèi)容在作者Github這一章節(jié)的README上有伏伯。
-
Exit Status: How to Programmatically Tell Whether Your Command Worked:Exit Status退出碼可以幫助我們知曉一個程序是否正確地運(yùn)行完成了。標(biāo)準(zhǔn)地來說捌袜,0 exit status就代表程序正確運(yùn)行了说搅,非0就代表不正確。
這就是有時候你程序跑錯了虏等,經(jīng)常會出現(xiàn)的Exit status XXX
$?代表了退出碼
$ program1 input.txt > results.txt $ echo $? 0
有時候弄唧,開發(fā)者在開放一款軟件的時候,會忘記考慮到退出碼這種情況霍衫。所以你會發(fā)現(xiàn)有時候錯誤地運(yùn)行了套才,還是zero-exit status。
-
退出碼是很有用的慕淡,因?yàn)樗梢宰屛覀冩準(zhǔn)降鼐幊瘫嘲椤<春笠粋€命令是否執(zhí)行取決于前一個命令的退出碼。
# 前一個命令成功,就執(zhí)行后續(xù)命令(&&) # 防止程序1失敗了傻寂,程序2還是讀這個文件 $ program1 input.txt > intermediate-results.txt && \ program2 intermediate-results.txt > results.txt # 前一個命令失敗息尺,就執(zhí)行后續(xù)命令(||) # 在輸出warning的時候比較有用 $ program1 input.txt > intermediate-results.txt || \ echo "warning: an error occurred"
如果狀態(tài)碼,只想連續(xù)執(zhí)行的話疾掰。就用
;
Command Substitution
-
命令替換可以把一個命令的輸出結(jié)果搂誉,嵌入另一個命令里面
$ grep -c '^>' input.fasta 416 $ echo "There are $(grep -c '^>' input.fasta) entries in my FASTA file." There are 416 entries in my FASTA file.
$()和``是等價的
-
使用這個命令,我們可以很方便地創(chuàng)建當(dāng)前時間文件夾
$ mkdir results-$(date +%F) $ ls results-2015-04-13
+%F 這種格式對于日期命令的文件夾是很有幫助的静檬,因?yàn)榈綍r候排序的時候就會按日期來排
$ ls -l drwxr-xr-x 2 vinceb staff 68 Feb 3 23:23 1999-07-01 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:22 2000-12-19 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:22 2011-02-03 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:22 2012-02-13 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:23 2012-05-26 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:22 2012-05-27 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:23 2012-07-04 drwxr-xr-x 2 vinceb staff 68 Feb 3 23:23 2012-07-05