我正在寻求解释并更深入地了解cat file | ...
vs ... < file
。
我正在为我的作业编写扫雷编码,它需要处理错误指令并在错误指令输入后终止程序。
但是,当我实验时,它将是命令。 {I} cat
命令没有让程序退出,直到我再按一次。但<
命令工作正常。
有人会告诉我cat input.in - | ./game4
如何工作以及为什么等待我再按一次进入?
我目前正在完成任务,一切进展顺利,我正在攻读悉尼大学。然而,他们无法回答我的问题。到目前为止,我对他们的经历非常糟糕。长话短说。 所以我会请任何人帮助我,因为我只是一个初学者,我已经尽力阅读所有类型的文档但是我并不擅长阅读纯文本而没有任何例子。
答案 0 :(得分:3)
Fiona,您提供了不必要使用猫(称为 UUoC )的完美示例。 cat
是连接的缩写。它的目的是将来自多个文件的文本连接(连接)到一个新文件中(例如cat file1 file2 file3 > newfile4
)当给出只有一个文件时,它的默认行为是连接到stdout
(这个默认行为是什么提示所有误用。)
cat input.in - | ./game4
不是连接表达式,您只是使用cat
将input.in
的输出重定向到game4
进程。 (您提供的额外'-'
表示stdin
是您的程序在输入内容之前等待的原因 - 在UUoC中不需要它)每次管道输出cat
时对于其他程序,您强制其他程序在另一个子shell 中不必要地运行。
您要做的是重定向输入到您的程序。这就是重定向运算符'<'
的用途。使用./game4 < yourinputfile
将输入重定向到程序时,不需要额外的子shell,重定向操作符正在执行创建它的操作。
如果你发现自己正在做cat whatever | ...
,你应该想到“呃!另一个UUoC,微笑,因为现在你已经了解了它的差异。
答案 1 :(得分:2)
Cat
cat
是一个连接文件的命令,现在-
被认为是一个标记,表示它应该从STDIN读取,在这种情况下是终端,所以:
cat file -
将首先回显file
的全部内容,然后通过命令行回显您说的所有内容。您可以按 Ctrl + D 表示已完成说明。
为了让cat
在file
被回复时关闭,您只需写一下:
cat file
但这是useless use of cat
的一个很好的例子。
您描述的是管道(|
)。如果在两个命令之间放置一个管道,例如:
command1 | command2
command1
的输出作为输入提供给command2
。所以,如果你写:
cat file | command
它会将file
的内容提供给command
。
<
不是命令,它是 I / O重定向的示例之一。这一行:
command < file
表示您将file
的内容作为输入提供。
cat file | command
和
command < file
是等价的,尽管
cat
版本的计算成本可能更高。但cat file - | command
不是。
答案 2 :(得分:1)
<强> 强>
cat
强>
在没有重定向的最简单形式中cat
只接受一个参数 - 一个文件,读取它并将其文本内容放到STDOUT
上,这通常会在终端中看到。< / p>
如果您传递多个文件名,
cat
也可以将多个文件的内容放在STDOUT
上。但是,在这种情况下,第二个参数是-
。这是什么意思?
嗯,根据Manual page cat(1) line 46
(在bash中通过man cat
访问):
没有FILE,或者当FILE是 - 时,读取标准输入。
所以,您首先将input.in
的内容放在STDOUT
中,然后在键盘上输入任何内容(STDIN
)。
给定的描述有点令人困惑,因为它使它听起来只适用于单个参数,但实际行为有些不同。这是真的cat - $filename
忽略第二个参数,但如果你将-
作为最终参数(例如cat $filename -
),它显然会将STDIN
附加到结果中,即使有一个或多个文件,有些与描述相反。
|
将这些命令发送到您的游戏程序。
注意:您会在STDIN
中看到您输入内容的两个副本,但游戏只会看到一个。
要了解有关重定向的更多信息,我建议使用以下资源:
https://unix.stackexchange.com/questions/159513/what-are-the-shells-control-and-redirection-operators
http://wiki.bash-hackers.org/syntax/redirection
http://www.catonmat.net/download/bash-redirections-cheat-sheet.pdf
答案 3 :(得分:0)
没有一个答案提及过滤程序。
cat
是一类称为过滤程序的最简单的程序。有很多,例如grep
,tail
,head
,sed
等。过滤程序将一个或多个文件名作为参数从左到右处理。输出发送到标准输出,通常缩写为stdout
(来自C)。
一个重要的功能是如果您不提供任何文件名,会发生什么。然后,过滤器程序将从标准输入中读取,通常缩写为stdin
。默认情况下,stdin
已连接到键盘,但shell可以将其重定向为来自文件(<
)或管道(|
)。
请记住,stdin
的重定向是 shell 的函数,而不是过滤器程序。
cat foo.txt
具有与以下相同的功能:
cat < foo.txt
除第一个示例中的之外,程序cat
打开并读取文件。第二个是 shell 。
你觉得这里发生了什么?
cat foo.txt < bar.txt
试试吧!为什么不显示bar.txt
?由于提供了文件名,因此cat
无需阅读stdin
。
连字符-
通常用于表示“从标准输入读取”。所以我们可以这样做:
cat - foo.txt < bar.txt
将会读取并显示bar.txt
,然后显示foo.txt
。
这会做什么?
echo 'Hello' | cat foo.txt - bar.txt
试试吧!
修改强>
虽然您只能有一个stdin
,但您可以合并文件描述符:
3<&0 echo 'hello' >&3|cat < gash.txt
文件描述符(FD)只是一个引用IO流的整数。每个进程都有一个文件描述符表。按照惯例(几乎是法律,但不完全是):
FD 0 stdin
FD 1 stdout
FD 2 stderr
您可以看到FD 3以后可供程序免费使用。在上面复杂的例子中:
3<&0
将文件描述符0(stdin)复制到文件描述符3上(有关低级别机制,请参阅man dup2
)。需要&
来区分FD和名为“0”的文件。所以现在我有两个指向stdin的文件描述符!我将echo
重定向到FD 3,然后从文件重定向FD 0(<&0
是<
的默认值。)
输出重定向的语法实际上是[FD]> filename
,其中FD是可选的(这是[ ]
的意思)。写入时的默认FD为1,stdout。
创建新进程时,文件描述符表将从父级复制到子级。因此,当您从shell运行cat
时,对shell执行的所有文件描述符更改都将复制到cat
程序。