私はチュートリアルを進めていて、両方の使用を見ましたcat myfile.txt
およびcat < myfile.txt
。これらの2つのコマンドシーケンスの間に違いはありますか?どちらもファイルの内容をシェルに出力するようです。
最初のケースではcat
がファイルを開き、2番目のケースではシェルがファイルを開き、cat
の標準入力として渡します。
技術的には、それらは異なる効果を持つ可能性があります。たとえば、cat
プログラムよりも多かれ少なかれ特権を与えられたシェル実装を持つことが可能です。そのシナリオでは、1つはファイルを開くことができず、もう1つは開くことができます。
これは通常のシナリオではありませんが、シェルとcat
は同じプログラムではないことを指摘するために言及しました。
テストケースに目に見える大きな違いはありません。最も明白なのは、現在のディレクトリに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の返信と添付のコメントですでに示唆されているように、動作に大きな違いが生じます。
cat myfile.txt
は、ファイルmyfile.txt
を読み取り、標準出力に出力します。
cat < myfile.txt
here cat
には開くファイルが指定されていないため、多くのUnixコマンドと同様に、file.txt
から送信される標準入力からデータを読み取りますシェルによって、標準出力に出力します。
@ 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が使用していないリダイレクトでも発生します)。 どちらの場合も、誤った終了コードが返されます。
別のコマンドを使用して、次の違いを確認できます。
wc –w food2.txt
可能な出力:
6 food2.txt
コマンドはファイル名を知っている(引数として渡される)ため、ファイル名を通知します。
wc –w < food2.txt
可能な出力:
6
コマンドがファイルの名前を知らなくても、標準入力はファイルfood2.txt
にリダイレクトされます。