`>> / dev / stderr`(带有空格)和`>&2`有什么区别?


11

猛扑

我在确定应该使用什么方面遇到一些困难?

我所有的脚本都使用“ >> / dev / stderr”

在bash提示下,如果我尝试:
echo test >>/dev/stderrworks
echo test >> /dev/stderrworks
echo test >/dev/stderrworks
echo test > /dev/stderrworks

echo test >>&2失败!
echo test >> &2失败!
echo test >&2作品
echo test > &2失败!

我愿意将所有脚本更改为>&2

它对ssh似乎也有很大的影响(在之后su SomeUser),在ssh >>/dev/stderr根本不起作用(权限被拒绝),只会>&2起作用。


您可以显示ssh错误的示例吗?我无法复制它。
Jeff Schaller

@JeffSchaller你是对的,只是在su问题发生后,才更新问题
Aquarius Power

@AquariusPower,...顺便说明一下这种差异:使用su -c 'some command',该命令由/bin/sh而不是来运行bash,因此bash特定的行为(例如/dev/stderr在不可用时进行重定向目的模拟)不能保证存在。
查尔斯·达菲,

Answers:


22

>& n是Shell语法,用于直接复制文件描述符。文件描述符2是stderr;那就是它的工作方式。您也可以复制其他文件描述符,而不仅仅是stderr。您不能在此使用追加模式,因为复制文件描述符永远不会被截断(即使您的stderr是一个文件)并且>&是一个令牌,这就是为什么您不能在其中放置空格而是>& 2可以使用的原因。

>> name是不同的允许语法,其中name是文件名(令牌是>>)。在这种情况下,您使用的是文件名/dev/stderr,通过操作系统特定的处理(在Linux上是的符号链接/proc/self/fd/2),这也意味着标准错误。当stderr是终端时,append和truncate模式都会做同样的事情,因为它不能被截断。但是,如果标准错误是文件,它将被截断:

anthony@Zia:~$ bash -c 'echo hi >/dev/stderr; echo bye >/dev/stderr' 2>/tmp/foo
anthony@Zia:~$ cat /tmp/foo
bye

如果通过/dev/stderrover ssh 看到错误,则服务器管理员可能已应用了一些安全措施,从而阻止了该符号链接的工作。(例如,您无法访问/proc/dev)。虽然我希望这两种方法都可能导致各种奇怪的损坏,但是使用重复文件描述符语法是一种完全合理的方法(并且可能效率更高)。我个人更喜欢它。


我在尝试复制以前遇到的截断问题时遇到了很大的麻烦(否则我会在问题中加上这个问题),原因是我更改了所有要使用的内容>>,谢谢指出!另外,su SomeUser通过ssh连接后,我错过了一步。
Aquarius Power

bash -c 'echo hi >&2; echo bye >&2' 2>/tmp/foo;cat /tmp/foo不会截断!(即使使用2>&1 |tee /tmp/foo)最适合记录的内容,在我将其全部更改为之后,也可以正常使用>&2。因此,我想只有直接使用文件才能被/dev/stderr截断,而不是重复的描述符,太酷了!
Aquarius Power

@AquariusPower正确,重复的文件描述符永远不会被截断。在第一段中,也许我需要以某种方式突出显示它?
derobert

不需要,有时候我很慢
水瓶座力量

3
这个答案可以改善。>&是一个令牌,而不是两个令牌,而在于OP的混乱。
约书亚

8

发生失败情况是因为在重定向中使用的bash语法&指定了single >,并且要求它直接存在于&符号附近:

[n]>&word


2

使用'>'重定向(截断如果存在)或'>>'(追加如果不存在)。

使用'>&'复制流,例如,如果你想在同一个文件的标准输出和标准错误,您重定向到文件'> output.log',也有错误'2>&'

myjob.sh > output.log 2>&
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.