为什么命令;ls -l file_doesnot_exists > /dev/null 2>&1 正在工作;ls -l 2>&1 file_doesnot_exists > /



我只是想知道如何知道我们通常首先在 shell 命令中放置哪个指令? 例如 为什么命令:

ls -l file_doesnot_exists > /dev/null 2>&1

正在工作,而此命令:

ls -l 2>&1 file_doesnot_exists > /dev/null

注意:

  • 该问题被标记为linux,这意味着ls不是PowerShell自己的Get-ChildItemcmdlet(仅适用于Windows)的内置别名,而是指标准的/bin/lsUnix实用程序。

  • PowerShell中,命令之间没有区别,因为重定向的顺序无关紧要

    • 所有目标输出流始终保留其标识:流的任何重定向都会影响同一命令中到同一流的任何其他重定向。

    • 因此,您的两个命令都没有按预期工作并且不产生任何输出,因为当2>&1将错误流 (2) 重定向到成功输出流 (1时,后者的输出最终被丢弃,由于> /dev/null(>1>相同),包括重定向的错误流输出。

  • 相比之下,在POSIX 兼容的 shell(如 Bash)中,重定向的顺序确实很重要

    • ls -l 2>&1 file_doesnot_exists > /dev/null按预期工作

      • 2>&1将标准输出重定向到原始标准输出。
      • stdout的后续重定向(>1>相同)对2>&1没有影响
      • 净效果是只有标准输出行打印到 stdout,而标准输出行被丢弃(通过重定向到/dev/null)。
    • 相比之下,ls -l file_doesnot_exists > /dev/null 2>&1不会产生任何输出

      • > /dev/null将标准输出重定向到/dev/null,即有效地丢弃标准输出输出。

      • 由于命令后面出现2>&1,因此1引用已重定向的 stdout,因此 stderr 输出也会被丢弃。

    • 有关详细信息,请参阅此答案。

假设这是在PowerShell Core中运行的(因为标记表明它是),可以安全地假设你将bash命令与PowerShell cmdlet混淆。在 PowerShell 中,必须注意"终止"和"非终止"错误。

简而言之,ls -l 2>&1 file_doesnot_exists > /dev/null不起作用的原因是,ls(Get-ChildItem的别名)会产生一个终止错误,该错误会停止执行的其余部分,因为它缺少参数。这在Try {...} catch {...}语句中得到了证明,其中catch块">捕获"终止错误。

try {
ls -l
}
catch {
"it no workie"
}

由于lsGet-ChildItem的别名,因此 -L参数默认-LiteralPath它现在需要路径的位置,并且在运行时出错,因为它没有提供。

相关内容

  • 没有找到相关文章

最新更新