小なり記号がbashのcatの代わりとして機能しないのはなぜですか?


17

「猫の無駄な使用」について聞いたところ、いくつかの提案が見つかりましたが、次の例ではbashシェルに何も出力されません。

< 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
できます。あなたが試みたことは、ジョナサン・レフラーのコメントが示唆するものと同じではありません。
マナトワーク

「catの目的は、ファイルを連結(または「連結」)することです。ファイルが1つだけの場合、何も連結しないことは時間の無駄であり、プロセスにコストがかかります。」partmaps.org/era/unix/award.html
Bonsiスコット

回答:


22

より小記号と記号(<)は、ファイルを開いて、アプリケーション/プログラムの標準入力デバイスハンドルに添付します。ただし、シェルに入力をアタッチするアプリケーションを指定していません。

これらの2つの例は基本的に同じことを行いますが、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。2番目では、記述子番号0として識別されるSTDINファイル記述子を介してcatファイルの内容を読み取ることがわかりblah.txtます。

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

1
だから、猫の無駄な使用についてのこの話は偽ですか?
バグ

@バグ-いいえ、用途があります。しかしcat、一般的に誤解されており、必要でないときに使用されます。
slm

しかし、左から右への操作の順序を保持したい場合は必要ですか?コマンドの前で小なり構文を使用することも可能であると読みました。
バグ

@bug yesリダイレクトはコマンドの前後に発生する可能性があります。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

2
@Izkataは、の使い道がないという意味で「悪い」ものですcat
テルドン

"ダウン!テーブルを降りる!あなたは悪い猫です!」;-)しかし、真剣に…
G-Manは「Reinstate Monica」と言います

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」と言います

(続き)…(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は「Reinstate Monica」と言います

13

UUOCは次の場所にあります。

cat somefile | some-cmd

または

cat < somefile | some-cmd

そこから、それ自体がそれを読み取るパイプによって供給されるパイプからsome-cmdのコンテンツを読み取ります。somefilecatsomefile

some-cmdsomefile(シェルがstdinでそれを開いた後)から直接読み取ることができますcat

some-cmd < somefile

または

< somefile some-cmd

(リダイレクトは、単純なコマンドラインのどこにでも表示できます)。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.