
シェルのリダイレクト演算子を使用してコマンドに(存在しない)ファイル名を指定すると、grep
シェルはファイルが存在しないというエラーメッセージを表示します。ただし、コマンドに引数として同じファイル名を指定すると、grep
コマンド自体は対応するエラーメッセージを表示しますgrep
。なぜそんなことですか?
ここに私が言う内容のデモがあります。コマンドを実行するとき:
$ grep 'root' /etc/passw
次のエラーメッセージが表示されます。
grep: /etc/passw: No such file or directory
ただし、シェルリダイレクトを介してこのようにコマンドを実行すると、次のようになります。
$ grep 'root' < /etc/passw
代わりに、次のエラー メッセージが表示されます。
bash: /etc/passw: No such file or directory
入力ファイル名を指定するこの2つの方法の違いは何ですか?これを行うにはどういう意味ですか?
答え1
最初のコマンド($ grep 'root' /etc/passw
)で引数を指定すると、grep
それをファイル名として解釈して検索します。これgrep
は失敗するので、何が起こったのか教えてくれます。 grepは入力を解釈し、それに対して機能します。
2番目のコマンド()はgrep 'root' < /etc/passw
シェル(ここ:)を標準入力にbash
パイプします。 ()が見つからなかったので、これをあなたに伝えます。ここでbashはユーザーの入力を解釈し、それに応じてアクションを取ります。/etc/passw
grep
bash
2番目のコマンドは、概念的には、標準出力で指定されたファイルの$ bash-cat /etc/passw | grep 'root'
whereジョブを印刷するのと同じです。それからにリダイレクトされます。bash-cat
cat
grep
$ bash-cat /etc/passw | grep 'root'
bash-cat: /etc/passw: そのファイルやディレクトリはありません
-
パイプについて読んでみるとわかります。 (パイプライン:はじめに)
答え2
このようなI / Oリダイレクト演算子を使用すると、シェル自体はfd0からO_RDONLYへのコマンド入力への標準入力としてファイルを開きます。コマンドは読み取り可能ですが、引数として渡されると、コマンド自体が開いたファイルを処理します。
したがって、プログラム(例えばawk
)があり、<
リダイレクトを使用してファイル名を渡し、開いているファイルを印刷しようとすると報告されFILENAME
ます-
(入力が標準入力であることを意味します)。
awk '{ print FILENAME }' --infile
--infile
awk '{ print FILENAME }' <--infile
-
もう1つの利点は、ファイル名がハイフンで始まるとシェルがそれ自体を処理しますが、それをコマンドに引数として渡すと(例えばgrep
)、提供されたオプションが無効であると思うために文句を言うことです。
grep root --infile
grep: unrecognized option '--infile'
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
標準に準拠した標準コマンドは、--
コマンドにオプション引数が終了したことを通知することで、このエラーを防ぎます。ファイルへの絶対パスまたは相対パスを指定したり、./--infle
コマンドを使用してシェルにファイルを開くこともできますcommand <--infile
。
注:<inputfile command
isと同じバリアントを使用してくださいcommand <inputfile
。
別の利点は、ファイルが存在しない場合、またはシェルがファイルを開くことができない場合、コマンドは実行されないことです。
awk 'BEGIN{ print "ifrun" }' < non-existing_file
-bash: non-existing_file: No such file or directory
awk 'BEGIN{ print "ifrun" }' non-existing_file
ifrun