为什么小于号不能代替bash中的cat?


17

我听说过“猫的无用使用”并找到了一些建议,但是以下内容在我的bash shell中什么都没有输出。

< filename

使用cat的效果与预期的一样。

cat filename

我正在使用Fedora Core 18和GNU bash,版本4.2.45(1)。

编辑:在管道前使用它也不起作用。

< filename | grep pattern

而使用cat的效果可预期。

cat filename | grep pattern

EDIT2:澄清一下,我知道我可以使用它

grep pattern < filename

但我在这里阅读了/programming/11710552/useless-use-of-cat,我也可以在命令前使用它。但是,它不能在命令前运行。


2
有用。您所尝试的与Jonathan Leffler的评论所暗示的不一样。
manatwork 2013年

“ cat的目的是连接(或“连接”)文件。如果它只是一个文件,则根本不进行任何连接就是在浪费时间,并且要花很多时间。” partmaps.org/era/unix/award.html
Bonsi Scott

Answers:


22

小于和符号(<)正在打开文件,并将其附加到某些应用程序/程序的标准输入设备句柄。但是您还没有为Shell提供任何将输入附加到其中的应用程序。

这两个示例基本上做同样的事情,但是以2种略有不同的方式获得输入。

打开文件

$ cat blah.txt 
hi

开启STDIN

$ cat < blah.txt 
hi

在窗帘后面偷看

您可以使用 strace来查看发生了什么。

当我们从文件中读取

open("blah.txt", O_RDONLY)              = 3
fstat(3, {st_mode=S_IFREG|0664, st_size=3, ...}) = 0
fadvise64(3, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(3, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(3, "", 65536)                      = 0
close(3)                                = 0
close(1)                                = 0

当我们从STDIN读取时(标识为0)

read(0, "hi\n", 65536)                  = 3
write(1, "hi\n", 3hi
)                     = 3
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0

在第一个示例中,我们可以看到cat打开了文件并从中读取文件blah.txt。在第二个中,我们可以看到它通过STDIN文件描述符(标识为描述符编号0)cat读取文件的内容blah.txt

read(0, "hi\n", 65536)                  = 3

1
那么这个关于猫的无用使用的说法是假的吗?
错误

@bug-不,有用途。但是cat通常会被误解,并在不需要时使用。
slm

但是,当我想保留操作从左到右的顺序时是否有必要?我读到有可能在命令前面也使用小于构造。
错误

@bug是,重定向可以在命令之前或之后进行,请参见Stephane的答案,他也显示了此示例。
slm

啊,现在我明白了。我得写< filename command
错误

14

经典无用 cat是当您使用它为完全能够直接打开文件的程序提供输入时。例如:

cat file | grep foo
cat file | while read line; do echo "$line"; done
cat file | sed 's/a/b/'
cat file | awk '{print $1}'

grep foo file
while read line; do echo "$line"; done < file 
sed 's/a/b/' file
awk '{print $1}' file

也很好(<file可以在命令的任何一侧)

<file grep foo
 sed 's/a/b/' < file
<file awk '{print $1}' 

6
这里的“不良”是主观的。我觉得这些是更好的整体,因为它的方式更一致,更易于阅读。数据流是完全从左到右的,如果涉及更多管道,应该是这样
Izkata 2013年

2
@Izkata从某种意义上来说是无用的,它们是“不好的” cat
terdon

“下!下车吧!你真是坏猫!” ;-)但要认真地……
G-Man说'Reinstate Monica''July

1
值得注意的是好(或者,至少,有用)的用途cat包括:(1) cat file(与输出到屏幕/终端;但是,如果该文件是长于屏幕是高,你可能更愿意使用moreless或类似的东西), (2) cat file1 file2 file3 > all_data究竟是什么cat意思了),(3) cat f1 f2 f3 | tr …(或管道到任何其他程序,你不想直接传递文件;例如,wc(例如,如果你想看到的总计只),或grep(例如,如果您有一个不支持的旧版本-h,即--no-filename)),…(续)
G-Man说'Reinstate Monica'15

(续)…(4)cat -n file | sort … -k1 | sed 's/^ *[0-9]*\t//',(5)sudo cat file600 | untrusted_program(即,(您的UID)无法读取文件,并且您不想以root用户甚至任何半特权的UID运行该程序)。另外,( e)(即2到3之间的数字)program_that_generates_html | cat static_html_header - static_html_footer(您可能希望将其重定向到文件或管道)。
G-Man说'恢复莫妮卡'

13

UUOC位于:

cat somefile | some-cmd

要么

cat < somefile | some-cmd

在那里,some-cmd正在somefile从管道读取内容,而管道cat本身就是从管道读取内容somefile

some-cmd可以直接从中读取somefile(shell在stdin上为其打开后),不需要cat

some-cmd < somefile

要么

< somefile some-cmd

(重定向可以出现在简单命令行的任何位置)。

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.