【发布时间】:2014-12-24 18:15:00
【问题描述】:
我最近从 CentOS 5.8(带有 GNU bash 3.2.25)升级到 CentOS 6.5(带有 GNU bash 4.1.2)。一个曾经适用于 CentOS 5.8 的命令不再适用于 CentOS 6.5。这是一个简单的解决方法的愚蠢示例,但我试图了解导致不同行为的 bash 引擎盖下发生的事情。可能是 bash 4.1.2 中的一个新 bug,或者是一个已修复的旧 bug,新的行为是预期的?
CentOS 5.8:
(echo "hi" > /dev/stdout) > test.txt
echo $?
0
cat test.txt
hi
CentOS 6.5:
(echo "hi" > /dev/stdout) > test.txt
-bash: /dev/stdout: Not a directory
echo $?
1
更新:看起来这不是与 CentOS 版本有关的问题。我有另一台 CentOS 6.5 机器,该命令可以运行。我已经消除了任何环境变量作为罪魁祸首。有任何想法吗? 在所有机器上,这些命令给出相同的输出:
ls -ld /dev/stdout
lrwxrwxrwx 1 root root 15 Apr 30 13:30 /dev/stdout -> /proc/self/fd/1
ls -lL /dev/stdout
crw--w---- 1 user1 tty 136, 0 Oct 28 23:21 /dev/stdout
另一个更新:似乎子 shell 正在继承父 shell 的重定向标准输出。我猜这并不太令人惊讶,但为什么它仍然可以在一台机器上运行,但是当它们运行相同的 bash 版本时在另一台机器上失败?
在工作机器上:
((ls -la /dev/stdout; ls -la /proc/self/fd/1) >/dev/stdout) > test.txt
cat test.txt
lrwxrwxrwx 1 root root 15 Aug 13 08:14 /dev/stdout -> /proc/self/fd/1
l-wx------ 1 user1 aladdin 64 Oct 29 06:54 /proc/self/fd/1 -> /home/user1/test.txt
我认为 Yu Huang 是对的,重定向到 /tmp 在两台机器上都有效。两台机器都使用 isilon NAS 进行 /home 挂载,但可能其中一台的文件系统版本或配置略有不同,导致错误。总之,应该避免重定向到 /dev/stdout,除非你知道父进程不会重定向它。
更新:从 v3 升级到 NFS v4 后出现此问题。降级回 v3 后,此行为消失了。
【问题讨论】:
-
为什么不干脆做:
echo "hi" > test.txt? -
@user1999165:它适用于 RHEL 5 和 6。
ls -ld /dev/stdout的发布输出。 -
这是一个非常奇怪的错误信息。从表面上看,这意味着
/dev不是目录,但这是非常非常不可能的。 -
@JonathanLeffler 是说
/dev/stdout不是目录,这是真的,但似乎并不相关。无论如何,(echo "hi" > /dev/stdout) > test.txt应该做什么?同时输出到/dev/stdout和test.txt?我以为这就是tee的用途。 -
@ooga:如果问题出在
/dev/stdout,它会说“没有这样的文件或目录”(或者“是目录”是/dev/stdout神秘地是一个目录); “不是目录”意味着路径上的元素不是目录,路径上唯一可能出现问题的元素是/和/dev— 尽管我不认为我相信.(echo "hi" > /dev/stdout)将 sub-shell 的echo的输出重定向到标准输出,无论如何这就是它要去的地方;> test.txt发送文件test.txt的标准输出。这一切都只是有点奇怪。
标签: linux bash redirect centos stdout