我想知道在shell命令中通常要先放哪个指令?例如,为什么这个命令:
ls -l file_doesnot_exists > /dev/null 2>&1
能运行,而这个命令:
ls -l 2>&1 file_doesnot_exists > /dev/null
不能。
我想知道在shell命令中通常要先放哪个指令?例如,为什么这个命令:
ls -l file_doesnot_exists > /dev/null 2>&1
能运行,而这个命令:
ls -l 2>&1 file_doesnot_exists > /dev/null
不能。
注意:
linux
,这意味着ls
不是PowerShell自己的Get-ChildItem
cmdlet的内置别名(仅适用于Windows),而是指标准的/bin/ls
Unix实用程序。在PowerShell中,你的命令没有区别,因为重定向的顺序不重要。
所有目标输出流始终保持其身份:任何流的重定向会影响同一命令中相同流的其他重定向。
因此,两个命令都不按预期工作,产生没有输出的结果,因为2>&1
将错误流(2
)重定向到成功输出流(1
),后者的输出最终会被丢弃,因为>/dev/null
(>
等同于1>
), 包括被重定向的错误流输出。
相比之下,在兼容POSIX的shell,例如Bash中,重定向的顺序很重要:
ls -l 2>&1 file_doesnot_exists > /dev/null
按预期工作:
2>&1
将stderr输出重定向到原始的stdout。>
等同于1>
)对2>&1
没有影响/dev/null
)丢弃了。相比之下,ls -l file_doesnot_exists > /dev/null 2>&1
不起作用并产生没有输出:
>/dev/null
将stdout重定向到/dev/null
,即有效地丢弃了stdout输出。
因为2>&1
出现在命令中较晚,所以1
引用已经重定向的stdout,以至于stderr输出也被丢弃。
有关更多信息,请参见此答案。
ls -l 2>&1 file_doesnot_exists > /dev/null
不起作用的原因是,ls
- 别名为 Get-ChildItem
- 会产生一个终止错误,它会停止执行其余的命令,因为它缺少一个参数。这在 Try {...} catch {...}
语句中得到了证明,在该语句中,catch
块“捕获”终止错误。try {
ls -l
}
catch {
"it no workie"
}
ls
是Get-ChildItem
的别名,因此参数-L
默认为-LiteralPath
,它现在期望一个路径,并且在运行时出错,因为没有提供路径。