使用破折号 (-) 代替文件名

使用破折号 (-) 代替文件名

对于命令,如果用作-参数代替文件名,则表示 STDIN 或 STDOUT。

  1. 但在本示例中,它创建一个名为的文件-

    echo hello > -
    

    我怎样才能-在这个例子中表示STDOUT?

  2. 相反,我怎样才能使示例中-命名的文件有意义-,例如:

    cat -
    

答案1

使用-文件名来表示 stdin/stdout 是许多程序使用的约定。它不是文件名的特殊属性。内核不认为是特殊的,因此任何引用文件名的-系统调用都将按字面意思使用文件名。--

使用 bash 重定向,-不会将其识别为特殊文件名,因此 bash 将使用它作为文字文件名。

cat将字符串-视为文件名时,它将其视为 stdin 的同义词。为了解决这个问题,您需要更改cat看到的字符串,使其仍然引用名为-.通常的方法是在文件名前加上路径 -./-/home/Tim/-.此技术还用于解决命令行选项与文件名冲突的类似问题,例如,称为 的文件./-e不会显示为-e程序的命令行选项。


1 除了>& filenamebash 最终从 csh 复制来重定向 stdout 和 stderr 的运算符之外,其中>&-仍然像在 Bourne shell 中一样关闭文件描述符,即使-被引用或扩展的结果也意味着>&无法使用该运算符对于任意文件名。请使用标准/Bourne> "$file" 2>&1语法或特定于 bash 的语法&> "$file"

答案2

  1. 相反echo hello > -,您可以使用echo hello > /dev/stdout.

    虽然“-”是每个想要支持它的程序必须实现的约定,/dev/stdin但当操作系统支持时(至少 Solaris、Linux 和 BSD 是这样), 、 和 是独立于应用程序的,然后将按照您的方式/dev/stdout工作/dev/stderr打算。

答案3

作为卡姆提到-只是某些程序使用的命名约定。如果您想使用 shell 能够识别的文件描述符来引用这些流,吉利亚格雷是正确的让您使用该名称/dev/stdin/dev/stdout代替。这些文件名应该适用于普通文件名可以使用的任何地方。

  1. 话虽这么说,你的第一个例子有点愚蠢。重定向运算符捕获并写入文件的任何输出都已经是标准输出,因此重定向它并将其写回它来自的位置是没有用的。您在那里使用的行为是管道,而不是重定向:

    echo hello |
    
  2. 在第二个示例中,您只需给出一些指示即可表明您想要该名称的垃圾文件,而不是它所具有的内部别名。您可以通过指定文件路径来最简单地完成此操作,如下所示:

    cat ./-
    

答案4

“-”方法有很多问题。首先,它需要对“-”字符进行解释,而许多程序不执行这种解释。此外,有些程序将连字符解释为标记命令行选项结束的分隔符。这些程序是为使用文件名参数而编写的,“-”方法是一种 hack,很好但很弱。

最好的办法是:

$ echo hello > /dev/fd/1

/dev/stdout是一个符号链接/dev/fd/1

相关内容