How is the stdout and stderr redirected here
我有这个:
1 | $ time 2>&1 sh 2>&1 -c"dd if=/dev/zero of=ddfile bs=512 count=125 && sync"> file |
125 + 0记录
125 + 0记录了
复制64000字节(64 kB),0.000617678 s,104 MB / s
真正的0m0.133s
用户0m0.000s
sys 0m0.020s
1 | $ cat file |
文件是空的。
问题:我理解
如果要重定向
1 | $ { time sh -c"dd if=/dev/zero of=ddfile bs=512 count=125 && sync"; } 2> file |
......产生:
1 2 3 4 5 6 7 8 | $ cat file 125+0 records in 125+0 records out 64000 bytes (64 kB) copied, 0.000617678 s, 104 MB/s real 0m0.133s user 0m0.000s sys 0m0.020s |
首先,除了一些例外,重定向通常发生在它们被写入的位置。它们从命令和参数序列中删除;只有剩下的,非重定向,单词参与。从而:
1 | 3>&1 foo 1>&2 arg1 2>&3 arg2 3>&- arg3 |
运行
(值得注意的例外是管道输出"先发生",即使管道符号位于简单命令部分的末尾。)
其次,正如pje所说,
在这种情况下,命令序列是一个简单的命令,带有重定向:
1 | 2>&1 sh 2>&1 -c ... > file |
每次重定向都发生在它写入的位置,剩下的序列是:
1 | sh -c ... |
重定向是:
所以
如果您运行:
1 | time 2>file dd if=/dev/zero of=ddfile bs=512 count=125 |
您将在stderr(例如,屏幕)上获得
如果你试试:
1 | 2>file time ... |
你会发现
1 | (time ...) 2>file |
或者如图所示的子块:
1 | { time ...; } 2>file |
(语法是笨拙的,子块作为空格和/或分号是必需的,但它避免了