fhi*_*iyo 21 shell bash io-redirection echo
当您想将 stdout 和 stderr 重定向到同一个文件时,可以使用command 1>file.txt 2>&1, 或command &>file.txt。但是为什么command 1>file.txt 2>file.txt与上面两个命令的行为不同呢?
以下是验证命令。
$ cat redirect.sh
#!/bin/bash
{ echo -e "output\noutput" && echo -e "error" 1>&2; } 1>file.txt 2>&1
{ echo -e "output\noutput" && echo -e "error" 1>&2; } 1>file1.txt 2>file1.txt
{ echo -e "error" 1>&2 && echo -e "output\noutput"; } 1>file2.txt 2>file2.txt
{ echo -e "output" && echo -e "error\nerror" 1>&2; } 1>file3.txt 2>file3.txt
{ echo -e "error\nerror" 1>&2 && echo -e "output"; } 1>file4.txt 2>file4.txt
$ ./redirect.sh
$ echo "---file.txt---"; cat file.txt;\
echo "---file1.txt---"; cat file1.txt; \
echo "---file2.txt---"; cat file2.txt; \
echo "---file3.txt---"; cat file3.txt; \
echo "---file4.txt----"; cat file4.txt;
---file.txt---
output
output
error
---file1.txt---
error
output
---file2.txt---
output
output
---file3.txt---
error
error
---file4.txt----
output
rror
Run Code Online (Sandbox Code Playgroud)
就结果来看,运行时第二个回显字符串似乎覆盖了第一个回显字符串command 1>file.txt 2>file.txt,但我不知道为什么会这样。(某处有参考吗?)
Jde*_*eBP 44
你需要知道两件事:
此类更改由调用read()/ readv()、write()/ writev()、lseek()等系统调用的进程执行。该echo命令当然会调用write()/ writev()。
所以发生的事情是这样的:
command 1>file.txt 2>&1只创建一个文件描述,因为 shell 只打开一个文件一次。壳品牌二者的标准输出和标准误差文件描述符映射到单个文件说明。它将标准输出复制到标准错误上。因此,通过任一文件描述符写入将移动共享的当前文件位置:每次写入都在前一次写入公共文件描述之后。正如您所看到的,echo命令的结果不会相互覆盖。command 1>file.txt 2>file.txt创建两个文件描述,因为 shell 两次打开同一个文件,以响应两个显式重定向。标准输出和标准错误文件描述符映射到两个不同的文件描述,然后又映射到同一个文件。这两个文件描述具有完全独立的当前文件位置,并且每次写入都紧跟上一次对同一文件描述的写入。正如您所看到的,结果是通过一个写入的内容可以覆盖通过另一个写入的内容,根据您执行写入的顺序以各种不同的方式。jes*_*e_b 16
使用>告诉它覆盖文件。由于您在两个不同的操作中将 stdout 和 stderr 写入文件,因此最后一个写入将覆盖第一个。
你可以做:
command 1>>file.txt 2>>file.txt
或者
command &>file.txt 仅 bash v4 及更高版本。
>> 告诉它附加文件,这样它就不会替换之前操作的输出。
&> 只是一种更简单的写作方式 2>&1
| 归档时间: |
|
| 查看次数: |
4144 次 |
| 最近记录: |