cat <> file`如何工作?


42

cat < file文件的内容打印到stdout。

cat > file读取标准输入,直到检测到Ctrl+ D并将输入文本写入文件

cat <> file,至少在我的Bash版本中,愉快地打印文件的内容(无错误),但不修改文件,也不更新修改时间戳。

Bash标准如何证明>在第三条陈述中似乎被忽略的理由?更重要的是,它在做什么?

Answers:


47

Bash用于<>创建读写文件描述符

重定向运算符

[n]<>word

导致打开名称为单词扩展的文件,以便在文件描述符n或未指定n的文件描述符0上进行读写操作。如果该文件不存在,则会创建它。

cat <> file打开file读写,并将其绑定到描述符0(标准输入)。从本质上讲,它等效< file于任何明智编写的程序,因为没有人可能会尝试按常规方式对标准输入进行写操作,但是如果可以的话,它就可以这样做。

你可以写一个简单的C程序直接测试出来- write(0, "hello", 6)将写入hellofile通过标准输入。

<>应该在任何其他POSIX兼容外壳中起作用,并且效果相同。


1
正在写...到stdin?...是否有任何有效的用例?
Qix 2014年

3
副手,我想不出任何好的。给出一个显式描述符(4<>file)很有用,我想默认值0与省略它时的默认值一样好。从stdout读取并没有更好的效果。
Michael Homer

5
<>在某些系统(例如Linux)上打开命名管道而不阻塞,直到另一个进程将其打开进行写入也很有用。
斯特凡Chazelas

1
@Qix:如果您打算像tty这样的提示,那么write(0,“ Password:”,10)是提示输入密码的好方法。我曾经只在stderr上看到过它,但没有理由特别指出,相同的技术在stdin上不起作用。
约书亚2014年

3
@Qix-来自POSIX基础 - <>操作员在编写可用于多个终端的应用程序时可能会很有用,并且偶尔想启动shell。除非它可以使用<>...这样的外壳,否则该外壳将无法运行从普通控制终端运行的应用程序,例如... pager more,它从标准错误中读取以获取其命令,因此是标准输入和标准输出都可以正常使用。 cat food | more - >/dev/tty03 2<>/dev/tty03
mikeserv 2014年

38

<> file读写模式打开文件(默认情况下,在文件描述符0(stdin)上,如<),不被截断如果事先不存在,则创建文件

这对应于O_RDWR|O_CREAT传递给open()系统调用的标志。相反,<is O_RDONLY>is O_WRONLY|O_CREAT|O_TRUNC>> O_WRONLY|O_CREAT|O_APPEND

使stdin可写通常不是有用的,因为应用程序通常不写入其stdin。应用程序通常不希望阅读,并在他们接受在启动时文件描述符写; 他们通常从stdin(或它们自己打开的文件描述符)中读取并写入stdout或stderr(或他们自己打开的文件描述符)。

<> 可以有其用途:

  • 您可能喜欢cat <> filecat < file,如果你不希望命令,如果失败,file不存在,但空的file创建来代替。
  • 的非截断方面<>使得覆盖原位文件很有用。但是,在那种情况下,通常不要在文件描述符0上使用它:

    printf xxx 1<> file

    取代了前3个字节的filexxx

  • 在某些系统上,例如Linux,<>在命名管道(FIFO)上打开该命名管道时不会阻塞(无需等待其他进程打开另一端),并确保该管道结构保持活动状态。例如在:

    mkfifo pipe; sed 's/foo/bar/g' <> pipe

    sed处理来自写入它的许多其他进程的传入数据,却从未发现过eof


1
请注意,在AT&T ksh93上,<>默认为1<>(stdout)而不是0<>(stdin)。这是我报告的POSIX合规性错误,将在下一版本中修复。github.com/att/ast/issues/75但在当前的ksh93版本不再使用之前,您必须包括文件描述符号以进行<>移植。
马丁·德克

@MartijnDekker,我知道,我是第一位告诉你的人;-)。请注意,仅适用于ksh93t +(行为已更改)及更高版本。
斯特凡Chazelas

有哪些(或曾经有) Linux 不同的系统mkfifo fifo; exec 3<>fifo会阻塞?
比利叔叔
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.