Charpter 3
这一章我觉得大家是可以好好看看的,这里面作者提到了一些我们有时候不太注意的概念:
- streams
- redirection
- pipes
- working with running programs
- command substitution
Working with Streams and Redirection
Working with Streams and Redirection Unix利用stream(流)这种文本处理哲学对于生信是非常有用的,它允许我们处理数据之间的流,而非将数据一股脑地保存在内存里面。 想象一下,如果你想要整合两个超大的文件在一起,正常操作是,打开一个大文件,复制,然后打开另一个大文件,粘贴到另一个大文件里面。这里的每一步都会耗费很大的内存。但Unix则会将整合的两个大文件的内容打印到 standard output stream(标准输出流),然后我们可以从终端重定向标准输出流到我们想要的文件。
-
Redirecting Standard Error 标准错误流是用来输出errors, warnings, and messages meant to be read by the user。
默认情况下,标准输出流和标准错误流如果没有重定向的话,都是输出到终端上的。但也可以输出到文件。
$ 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操作系统就为我们提供了一个虚假的储存(pseudodevice):/dev/null 。凡是写到/dev/null里的都会消失。
tail有一个骚操作是tail -f。设想一下你把标准错误流写到了stderr.txt文件里面,你可能会用tail时不时地看下,看有什么报错信息。但用了tail -f,你就可以持续地监控这个文件了。
-
Using Standard Input Redirection Unix也提供一种叫标准输入流(standard input )的重定向操作。通常情况下,标准输入流是来自于你的键盘。但是用 < 这个重定向操作符,我们也可以直接从一个文件里面读取标准输入流。
# 从inputfile输入标准输入流,然后标准输出流到outputfile $ program < inputfile > outputfile
事实上,许多程序也可以直接用file参数来读取文件,而不通过标准输入流。有些程序(生信里面很多)则会用 - 这个符号来表示他们应该用标准输入流。
The Almighty Unix Pipe: Speed and Beauty in One 管道跟我们上面提到的重定向很像,但其不是重定向一个程序的结果到一个文件,而是把程序的结果重定向成另一个程序的标准输入。但标准错误还是定向到你的终端屏幕上。
管道可以连接grep,cat等一系列程序。还可以连接其他语言的输入和输出。
-
Combining Pipes and Redirection 假如progarm 1是对input.txt 执行操作,然后输出结果到标准输出流,输出诊断结果到标准错误流。而program 2则是接受program 1的输出作为输入,然后也输出诊断结果到标准错误流。这时候,如果我们还是按正常操作,program 1和2的诊断结果就会在屏幕上混淆。但我们可以这样
program1 input.txt 2> program1.stderr | \ program2 2> program2.stderr > results.txt
-
因为管道只能连接标准输出流。但如果我们想同时在结果里面看到标准输出流和标准错误流的信息。那么就可以把标准错误流重定向到标准输出流那里。
# 2>&1 操作就是把标准错误流重定向到标准输出流 $ program1 2>&1 | grep "error"
-
Even More Redirection: A tee in Your Pipe 另一个骚操作:储存中间文件。
# 用了tee操作,既可以把program1的标准输出流储存成中间文件,也可以输出给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
-
当我们在shell里面开始运行命令之后,我们是不能再对shell进行操作的。短的命令还好,长的命令就非常地蛋疼了。这时候我们就可以在运行命令时候加入 &,来让其在后台运行。
# 这里的26577是proces ID或者说PID(进程ID) $ program1 input.txt > results.txt & [1] 26577 # 这里的1是jobs IDs $ jobs [1]+ Running program1 input.txt > results.txt
-
为了把后台运行的命令带到前台来,就可以用fg(for foreground)命令。当你的后台有许多的命令的时候,fg %<num>就可以选择把对应的进程带到前台来。
<num>就是所谓的jobs ID。
当你的后台进程只有一个的时候,fg和fg %1是等效的。
关闭我们的终端,会发送一个Hangup signal(SIGHUP)信号给由已关闭终端之前开启的所有进程。然后那些进程受到这些信号之后,几乎都会立刻停止运行。
-
也可以把前台运行的放到后台去。这时候你需要先用ctrl+z发送挂起信号(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
杀进程这部分详细内容在作者Github这一章节的README上有。
-
Exit Status: How to Programmatically Tell Whether Your Command Worked:Exit Status退出码可以帮助我们知晓一个程序是否正确地运行完成了。标准地来说,0 exit status就代表程序正确运行了,非0就代表不正确。
这就是有时候你程序跑错了,经常会出现的Exit status XXX
$?代表了退出码
$ program1 input.txt > results.txt $ echo $? 0
有时候,开发者在开放一款软件的时候,会忘记考虑到退出码这种情况。所以你会发现有时候错误地运行了,还是zero-exit status。
-
退出码是很有用的,因为他可以让我们链式地编程。即后一个命令是否执行取决于前一个命令的退出码。
# 前一个命令成功,就执行后续命令(&&) # 防止程序1失败了,程序2还是读这个文件 $ program1 input.txt > intermediate-results.txt && \ program2 intermediate-results.txt > results.txt # 前一个命令失败,就执行后续命令(||) # 在输出warning的时候比较有用 $ program1 input.txt > intermediate-results.txt || \ echo "warning: an error occurred"
如果状态码,只想连续执行的话。就用
;
Command Substitution
-
命令替换可以把一个命令的输出结果,嵌入另一个命令里面
$ 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.
$()和``是等价的
-
使用这个命令,我们可以很方便地创建当前时间文件夹
$ mkdir results-$(date +%F) $ ls results-2015-04-13
+%F 这种格式对于日期命令的文件夹是很有帮助的,因为到时候排序的时候就会按日期来排
$ 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