首先,我们有一些命令:
service --status-all 1>one 2>one
service --status-all 1>two 2>>two
service --status-all 1>>three 2>>three
service --status-all 1>>four 2>four
service --status-all 2>one1 1>one1
service --status-all 2>two1 1>>two1
service --status-all 2>>three1 1>>three1
service --status-all 2>>four1 1>four1
执行后,以下内容相同:
three = three1 ,所以这些是相同的:
service --status-all 1>>three 2>>three
service --status-all 2>>three1 1>>three1
one = four = one1 = two1 ,所以这些是相同的:
service --status-all 1>one 2>one
service --status-all 1>>four 2>four
service --status-all 2>one1 1>one1
service --status-all 2>two1 1>>two1
两个= four1 ,所以这些是相同的:
service --status-all 1>two 2>>two
service --status-all 2>>four1 1>four1
文件一个 = 四个 = one1 = two1 :
[ ? ] apport
[ ? ] binfmt-support
[ ? ] console-setup
[ ? ] dns-clean
[ ? ] irqbalance
[ ? ] killprocs
[ ? ] kmod
[ ? ] lightdm
[ ? ] mysql
[ ? ] networking
[ ? ] ondemand
[ ? ] pppd-dns
[ ? ] rc.local
[ ? ] sendsigs
[ ? ] speech-dispatcher
[ ? ] umountfs
[ ? ] umountnfs.sh
[ ? ] umountroot
] sudo
[ - ] udev
[ - ] unattended-upgrades
[ - ] urandom
[ + ] virtualbox
[ - ] x11-common
文件两个 = four1 :
[ + ] acpid
[ - ] anacron
[ - ] apparmor
[ + ] avahi-daemon
[ + ] bluetooth
[ - ] brltty
[ + ] cron
[ + ] cups
[ + ] cups-browsed
[ - ] dbus
[ + ] friendly-recovery
[ - ] grub-common
[ + ] kerneloops
[ - ] procps
[ - ] pulseaudio
[ + ] resolvconf
[ - ] rsync
[ + ] rsyslog
[ + ] saned
[ - ] sudo
[ - ] udev
[ - ] unattended-upgrades
[ - ] urandom
[ + ] virtualbox
[ - ] x11-common
nfs.sh
[ ? ] umountroot
文件三 = three1 :
[ + ] acpid
[ - ] anacron
[ - ] apparmor
[ ? ] apport
[ + ] avahi-daemon
[ ? ] binfmt-support
[ + ] bluetooth
[ - ] brltty
[ ? ] console-setup
[ + ] cron
[ + ] cups
[ + ] cups-browsed
[ - ] dbus
[ ? ] dns-clean
[ + ] friendly-recovery
[ - ] grub-common
[ ? ] irqbalance
[ + ] kerneloops
[ ? ] killprocs
[ ? ] kmod
[ ? ] lightdm
[ ? ] mysql
[ ? ] networking
[ ? ] ondemand
[ ? ] pppd-dns
[ - ] procps
[ - ] pulseaudio
[ ? ] rc.local
[ + ] resolvconf
[ - ] rsync
[ + ] rsyslog
[ + ] saned
[ ? ] sendsigs
[ ? ] speech-dispatcher
[ - ] sudo
[ - ] udev
[ ? ] umountfs
[ ? ] umountnfs.sh
[ ? ] umountroot
[ - ] unattended-upgrades
[ - ] urandom
[ + ] virtualbox
[ - ] x11-common
有18个问号(stderr线)。 Stderr明显覆盖了前18行stdout,然后是一些(sudo line)。
为什么会出现这种行为?
我的操作系统是Ubuntu 14.04。
答案 0 :(得分:1)
在每次写入之前,为自动附加而打开的流会自动将自身重新定位到文件末尾。如果另一个流在其两个写入之间写入文件,它将重新定位。
另一方面,为正常输出打开的流不会重新定位。如果附加流写入某些内容,然后普通流写入内容,则第二次写入将覆盖第一次写入的内容。
此外,如果程序使用stdio
,则某些写入可能会被缓冲。刷新缓冲区时会发生上述行为,而不是在程序调用缓冲的写入函数时。默认情况下,stdout
在写入文件时是完全缓冲的,stderr
是无缓冲的。
答案 1 :(得分:0)
您实际看到的奇怪行为实际上与重定向顺序无关,而且与输出缓冲和传递给open()的标志有关。
您使用O_APPEND [正如>>
所做的那样]打开您的一个文件 - 因此所有的写入将始终结束 - 而另一个写入>
因此缺少保证。此外,正如您报告的行为所证明的那样,您的程序不会对其写入执行行缓冲,这意味着您的写入会被拆分为大块,这些块不能保证在行边界处结束并且这些块是散布的
如果您的程序执行了行缓冲写入,则可以使用>>
作为两个文件描述符,并且事情通常会起作用(只要这些行足够短以便由单个write()
完成呼叫)。但是,它没有,所以你不能以这种方式拆分和重新组合它的输出,并期望事物在线边界上分开。
现在,回答有关重定向顺序的字面问题(它与手头问题的实际原因没有任何关系):
严格地从左到右。