shell: 深入理解 bash redirection 重定向
June 5, 2015
Table of Contents
stdout redirection
➜ ganiks@bash-redirection cat 123 11111111 22222222 33333333 ➜ ganiks@bash-redirection cat 123 >> abc ➜ ganiks@bash-redirection echo "one line>" >> abc #当cat不带参数的时候,表示使用标准输入作为输入,这允许在标准输入中键入相关的内容 ➜ ganiks@bash-redirection cat >> abc 44444444 55555555 66666666^C # ctrl+C ➜ ganiks@bash-redirection cat abc 11111111 22222222 33333333 one line 44444444 55555555 66666666
stderr to stdout
➜ ganiks@bash-redirection cat > find.sh find . -name "*>" -print -exec grep "555>" {} ; ^C ➜ ganiks@bash-redirection sudo chmod +x find.sh ➜ ganiks@bash-redirection ./find.sh . grep: .: 是一个目录 ./abc 55555555 ./nginx-V ./find.sh find . -name "*>" -print -exec grep "555>" {} ; ./123 #第一种情况 ➜ ganiks@bash-redirection ./find.sh 2>&1 > find1.log grep: .: 是一个目录 grep: 输入文件 ‘./find1.log’ 同时也作输出 #第一种情况 ➜ ganiks@bash-redirection ./find.sh > find2.log 2>&1 #结果1 ➜ ganiks@bash-redirection cat find1.log . ./abc 55555555 ./nginx-V ./find.sh find . -name "*>" -print -exec grep "555>" {} ; ./123 ./find1.log #结果2 ➜ ganiks@bash-redirection cat find2.log . grep: .: 是一个目录 ./abc 55555555 ./nginx-V ./find.sh find . -name "*>" -print -exec grep "555>" {} ; ./123 ./find1.log 55555555 find . -name "*>" -print -exec grep "555>" {} ; ./find2.log grep: 输入文件 ‘./find2.log’ 同时也作输出
0 是 stdin
1 是 stdout
2 是 stderr
➜
./find.sh 2>&1 > find1.log
➜
./find.sh > find2.log 2>&1
这里分析的关键是:一步一步分析,分析一步,输出一步
-
第一种情况:
- 2>&1: 将stderr定向到stdout, 原本stdout就是要到屏幕的,所以stderr会输出到屏幕
-
>find1.log : 将stdout 再重定向到文件
-
第二种情况:
-
>find2.log : 将stdout重定向到文件 - 2>&1: 将stderr重定向到stdout, 此时stdout已经到文件了,自然stderr也要到文件
-
重定向的过程其实很简单,但由于和直观感受不一致,往往导致初学者在这里犯很多错误。 参考文档
基本的IO重定向
基本IO重定向操作
-
> file : 将stdout重定向到file - < file: 将file作为stdin
- cmd1 | cmd2 : pipe,将cmd1 的标准输出作为cmd2 的标准输入
-
>>file :将标准输出重定向到file,如果file存在,append到文件中,即附加到文件的后面,而不是覆盖文件 - cat >> file: 当cat不带参数的时候,表示使用标准输入作为输入,这允许在标准输入中键入相关的内容
-
> | file : 强制将标准输出重定向到file,即使noclobber设置。当设置环境变量set –o noclobber,将禁止重定向到一个已经存在的文件中,避免文件被覆盖。 - n >|file: 强制将文件描述符n重定向到file,即使noclobber打开
- <>file: 将file作为标准输入和标准输出。通常用于设备文件(/dev下面的文件),底层系统程序员可用之测试设备驱动,其他的很少用
- n <>file: 将file作为文件描述符n的输入和输出
- << label: Here-document; : 将shell的标准输入作为命令的输入,直到行中之包含label。这中间的输入成为here-document。
➜ ganiks@bash-redirection cat >> msgfile <<.
heredoc> this is the text of
heredoc> our message
heredoc> end with .
heredoc> . #这里<<.表明以.为结束。因此无需使用^D,而改用.
➜ ganiks@bash-redirection cat msgfile
this is the text of
our message
end with . [/code]
- n>file :将文件描述符n重定向到file
- n :将file作为文件描述符的输入
- n>>file :将文件描述符n的输出重定向到file,如果file存在,将输出append到文件后面
- n>& :将标准输出复制到文件描述符n(Duplicate standard output to file descriptor n)
- n<& :从文件描述符n复制标准输入(Duplicate standard input from file descriptor n)
- n>&m :文件描述字n将一个copy至文件描述字m(File descriptor n is made to be a copy of the output file descriptor)
- n<&m :文件描述字n作为文件描述字m中的一个拷贝(File descriptor n is made to be a copy of the input file descriptor)
- &>file : 将标准输出和标准错误输出定向至文件file
- <&- : 关闭标准输入
-
>&- : 关闭标准输出 - n>&- : 关闭文件描述字作为输出(Close the output from file descriptor n)
- n<&- :关闭文件描述字作输入(Close the input from file descriptor n)
- n>&word: If n is not specified, the standard output (file descriptor 1) is used. If the digits in word do not specify a file descriptor open for output, a redirection error occurs. As a special case, if n is omitted, and word does not expand to one or more digits, the standard output and standard error are redirected as described previously.
- n<&word : If word expands to one or more digits, the file descriptor denoted by n is made to be a copy of that file descriptor. If the digits in word do not specify a file descriptor open for input, a redirection error occurs. If word evaluates to -, file descriptor n is closed. If n is not specified, the standard input (file descriptor 0) is used.
- n>&digit- : Moves the file descriptor digit to file descriptor n, or the standard output (file descriptor 1) if n is not specified.
- n<&digit- : Moves the file descriptor digit to file descriptor n, or the standard input (file descriptor 0) if n is not specified. digit is closed after being duplicated to n.
文件描述符
文件描述符在bash中比较少用,从0开始用户表示进行的数据流,0表示标准输入,1表示标准输出,2表示标注错误输出,其他从3开始。
最为常用的场景是将错误消息输出到某个文件,可以加上2>file 到我们的命令中。
我们来看下面一个脚本的例子:
command > logfile 2>&1 &
-
>logfile 表示command的标准输出重定向至文件logfile中 - 2>&1,匹配n>&m,表示文件描述字2(command的标准错误输出)将copy一份采用文件描述字1(即标准输出),由于标准输出已经重定向logfile,这份copy也见将重定向至文件lofgile。我们可以用“abcd > logfile 2>&1 &”来验证这个效果。
下面可达到类似的效果:
command 2>&1 | tee logfile &
错误输出同样适用标准输出,通过pipe方式,见他们作为输入执行tee logfile。tee命令将它的标准输入copy至他的标准标准输出以及参数所带的文件中。和上面的命令不一眼这里即会在stdout 和logfile中同时输出。
其他文件描述字的重定向,例如<&n,通常用于从多个文件中读入或者写出。
- <&- ,表示强制关闭标准输入
-
>&- ,表示强制关闭标准输出 - 1> ,等同于>
- 0< ,等同于<
原文:http://www.cnblogs.com/ganiks/p/deep-in-bash-redirection.html
0 Comments