深入理解 bash redirection 重定向stdout redirection? ganiks@bash-redirection cat 123 111111112222222233333333? ganiks@bash-redirection cat 123 >> abc ? ganiks@bash-redirection echo "one line" >> abc#当cat不带参数的时候,表示使用标准输入作为输入,这允许在标准输入中键入相关的内容? ganiks@bash-redirection cat >> abc444444445555555566666666^C # ctrl+C? ganiks@bash-redirection cat abc 111111112222222233333333one line444444445555555566666666
参考文档
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: .: 是一个目录./abc55555555./nginx-V./find.shfind . -name "*" -print -exec grep "555" {} \;./123#第一种情况? ganiks@bash-redirection ./find.sh 2>&1 > find1.loggrep: .: 是一个目录grep: 输入文件 ‘./find1.log’ 同时也作输出#第一种情况? ganiks@bash-redirection ./find.sh > find2.log 2>&1#结果1? ganiks@bash-redirection cat find1.log ../abc55555555./nginx-V./find.shfind . -name "*" -print -exec grep "555" {} \;./123./find1.log#结果2 ? ganiks@bash-redirection cat find2.log .grep: .: 是一个目录./abc55555555./nginx-V./find.shfind . -name "*" -print -exec grep "555" {} \;./123./find1.log55555555find . -name "*" -print -exec grep "555" {} \;./find2.loggrep: 输入文件 ‘./find2.log’ 同时也作输出
0 是 stdin1 是 stdout2 是 stderr
? ganiks at bash-redirection ./find.sh 2>&1 > find1.log? ganiks at bash-redirection ./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作为stdincmd1 | 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 ofheredoc> our messageheredoc> end with .heredoc> . #这里<<.表明以.为结束。因此无需使用^D,而改用. ? ganiks@bash-redirection cat msgfile this is the text ofour messageend with .
n>file :将文件描述符n重定向到filen :将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< ,等同于<