对于命令,如果用作-
参数代替文件名,则表示 STDIN 或 STDOUT。
但在本示例中,它创建一个名为的文件
-
:echo hello > -
我怎样才能
-
在这个例子中表示STDOUT?相反,我怎样才能使示例中
-
命名的文件有意义-
,例如:cat -
答案1
使用-
文件名来表示 stdin/stdout 是许多程序使用的约定。它不是文件名的特殊属性。内核不认为是特殊的,因此任何引用文件名的-
系统调用都将按字面意思使用文件名。-
-
使用 bash 重定向,-
不会将其识别为特殊文件名,因此 bash 将使用它作为文字文件名。
当cat
将字符串-
视为文件名时,它将其视为 stdin 的同义词。为了解决这个问题,您需要更改cat
看到的字符串,使其仍然引用名为-
.通常的方法是在文件名前加上路径 -./-
或/home/Tim/-
.此技术还用于解决命令行选项与文件名冲突的类似问题,例如,称为 的文件./-e
不会显示为-e
程序的命令行选项。
1 除了>& filename
bash 最终从 csh 复制来重定向 stdout 和 stderr 的运算符之外,其中>&-
仍然像在 Bourne shell 中一样关闭文件描述符,即使-
被引用或扩展的结果也意味着>&
无法使用该运算符对于任意文件名。请使用标准/Bourne> "$file" 2>&1
语法或特定于 bash 的语法&> "$file"
。
答案2
相反
echo hello > -
,您可以使用echo hello > /dev/stdout
.虽然“-”是每个想要支持它的程序必须实现的约定,
/dev/stdin
但当操作系统支持时(至少 Solaris、Linux 和 BSD 是这样), 、 和 是独立于应用程序的,然后将按照您的方式/dev/stdout
工作/dev/stderr
打算。
答案3
作为卡姆提到,-
只是某些程序使用的命名约定。如果您想使用 shell 能够识别的文件描述符来引用这些流,吉利亚格雷是正确的让您使用该名称/dev/stdin
或/dev/stdout
代替。这些文件名应该适用于普通文件名可以使用的任何地方。
话虽这么说,你的第一个例子有点愚蠢。重定向运算符捕获并写入文件的任何输出都已经是标准输出,因此重定向它并将其写回它来自的位置是没有用的。您在那里使用的行为是管道,而不是重定向:
echo hello |
在第二个示例中,您只需给出一些指示即可表明您想要该名称的垃圾文件,而不是它所具有的内部别名。您可以通过指定文件路径来最简单地完成此操作,如下所示:
cat ./-
答案4
“-”方法有很多问题。首先,它需要对“-”字符进行解释,而许多程序不执行这种解释。此外,有些程序将连字符解释为标记命令行选项结束的分隔符。这些程序是为使用文件名参数而编写的,“-”方法是一种 hack,很好但很弱。
最好的办法是:
$ echo hello > /dev/fd/1
/dev/stdout
是一个符号链接/dev/fd/1