web-dev-qa-db-ja.com

「cat」と「cat <」の違い

私はチュートリアルを進めていて、両方の使用を見ましたcat myfile.txtおよびcat < myfile.txt。これらの2つのコマンドシーケンスの間に違いはありますか?どちらもファイルの内容をシェルに出力するようです。

70
rookie

最初のケースではcatがファイルを開き、2番目のケースではシェルがファイルを開き、catの標準入力として渡します。

技術的には、それらは異なる効果を持つ可能性があります。たとえば、catプログラムよりも多かれ少なかれ特権を与えられたシェル実装を持つことが可能です。そのシナリオでは、1つはファイルを開くことができず、もう1つは開くことができます。

これは通常のシナリオではありませんが、シェルとcatは同じプログラムではないことを指摘するために言及しました。

107
Thomas Dickey

テストケースに目に見える大きな違いはありません。最も明白なのは、現在のディレクトリにmyfile.txtという名前のファイルがない場合、またはファイルの読み取りが許可されていない場合に表示されるエラーメッセージです。

前者の場合、catは文句を言い、後者の場合、シェルはどのプロセスがファイルを開こうとしているのかを明確に示します。前者の場合はcat、後者の場合はシェル1。

$ cat myfile.txt
cat: myfile.txt: No such file or directory
$ cat < myfile.txt
ksh93: myfile.txt: cannot open [No such file or directory]

より一般的なケースでは、主な違いは、リダイレクトを使用して複数のファイルの内容を印刷することはできないことです。つまり、catの本来の目的(つまりcat enate)コマンド。シェルはとにかくリダイレ​​クトされた入力として渡されたすべてのファイルを開こうとしますが、実際にはcatとそのzsh "zshism"を使用しない限り、最後のファイルのみをmultiosに渡します。 。

$ echo one > one
$ echo two > two
$ cat one two # cat opens one, shows one, opens two, shows two
one
two
$ cat < one < two # sh opens one then opens two, cat shows stdin (two)
two
$ rm one two
$ echo one > one
$ cat one two # cat opens and shows one, fails to open two
one
cat: two: No such file or directory
$ cat < one < two # the Shell opens one then opens two, fails and 
                  # displays an error message, cat gets nothing on stdin
                  # so shows nothing
ksh93: two: cannot open [No such file or directory]

標準システムでは、Shellとcatはファイルアクセス権に違いがないため、どちらも同じように失敗します。 Sudoを使用してcatの特権を上げると、Thomas Dickeyの返信と添付のコメントですでに示唆されているように、動作に大きな違いが生じます。

21
jlliagre

cat myfile.txtは、ファイルmyfile.txtを読み取り、標準出力に出力します。

cat < myfile.txt here catには開くファイルが指定されていないため、多くのUnixコマンドと同様に、file.txtから送信される標準入力からデータを読み取りますシェルによって、標準出力に出力します。

7
Hamza Abbad

@ Thomas Dickey の答えは素晴らしい。

いくつかのファイルを読み取る場合について、いくつかの明らかな事実を追加したいと思います(大まかにあなたの質問に関連していますが、それでも):

  • cat <file1 <file2 <file3は、少なくともbashではfile3のみを読み取ります。 (実際には、それはシェルに依存しますが、ほとんどのシェルは dup 指定されたすべてのファイルをstdinに送信します。これにより、最後のファイルが有効になります。)
  • cat file1 file2 file3は、指定されたすべてのファイルを順次読み取ります(実際にはcatは、Wordの短縮形concatenate)。
  • cat file1 file2 file3 <file4 <file5 <file6は、file1、file2、file3のみを読み取ります(ファイル名の引数が渡されたときにcatがstdinを無視するため)。
    • cat file1 file2 - file3 <file4 <file5 <file6は、file1、file2、file6、file3を読み取ります(ハイフンはcatにstdinを無視させないため)。

そしてエラーについて。 open 一部のファイルを引数として指定できない場合(<なし)、catは失敗したファイルをスキップし(関連するメッセージをstderrに出力して)、他のファイルを読み取ります。 (<を使用して)リダイレクトとして指定されたファイルの少なくとも1つを開くことができない場合、シェルはcatを開始しません(これは実際にcatが使用していないリダイレクトでも発生します)。 どちらの場合も、誤った終了コードが返されます。

6
sasha

別のコマンドを使用して、次の違いを確認できます。

wc –w food2.txt

可能な出力:

6 food2.txt

コマンドはファイル名を知っている(引数として渡される)ため、ファイル名を通知します。

wc –w < food2.txt

可能な出力:

6

コマンドがファイルの名前を知らなくても、標準入力はファイルfood2.txtにリダイレクトされます。

0
user307770