STDINとコマンドに渡された引数の違いは何ですか?

STDINとコマンドに渡された引数の違いは何ですか?

2つの形式のいずれかを使用してメソッドを実行できますcat

cat file_name
cat < file_name

結果は同じ

manその後、次の形式で実行したいと思います。stdin

man < file_name

また、以下がfile_name含まれます:

# file_name
cat

What manual page do you want?ただし、実行する代わりにポップアップが表示されます man cat

パラメータとしてcat受け入れられますが、なぜ受け入れられないのかを知りたいです。コマンドラインパラメータとの違いは何ですか?stdinmanstdin

答え1

問題は、使用中のシェルがコマンドラインからユーザー入力を解析する方法と密接に関連しています。

コマンドラインの最初の単語がプログラムで、特別なフォルダ(主に定義されているPATH)にあり、特殊文字が指定されていない場合(使用するシェルによって異なります)、スペースまたはタブで区切られたすべての後続の文字が渡されます。特別な形式の配列でプログラムに渡されます。各単語を配列の要素として扱います。

呼び出すプログラムがパラメータ(配列内にある)を解釈する方法は、プログラミング方法によって異なります。パラメータの構文がどのように見えるかについてのいくつかの準標準がありますが、通常、プログラマは完全に無料です。したがって、最初のパラメーターは、ファイル名またはプログラマーがプログラムを作成したときに思ったように解釈できます。

<特殊文字を追加するか>コマンドラインに追加すると、シェルはプログラムに渡される配列<に後続の単語を追加しません。あるいは、与えられた値を>使用すると、シェルはデフォルトのカーネル(キーワード)でサポートされている素晴らしいものを作成し始めます。<>管路)。何が起こっているのかを理解するには、STDINSTDOUTすぐには関係がないので省略しますSTDERR)が何であるかを理解する必要があります。

端末に表示されるすべてのもの(そしてほとんどの場合ディスプレイの一部)は特別なファイルです(Unixのすべてはファイルです)。このファイルには特別なIDがありますSTDOUT。プログラムがキーボードからデータを読み取ろうとする場合(少なくともほとんどの場合)、キーボードを直接ポーリングせずにSTDINファイルを内部的に接続します。標準入力デバイス(ほとんどの場合キーボード)

シェルが解析されたコマンドラインから OR を読み取ると、<そのプログラムの実行時に特定のタイプに対して OR が実行されます。これは、端末または標準入力デバイスを指すことなく、コマンドラインの後続のファイル名を指します。>STDINSTDOUTSTDINSTDOUT

2行の場合

cat file_name
cat < file_name

観察される動作は、その開発者がファイルまたはcat最初STDINのコマンドライン引数(シェルの最初の要素に渡された配列にあるcat)で名前付きファイルからデータを読み取るのと同じです。シェルに操作を指示するものではないため、orの内容全体がcat端末に書き込まれます。 2行目では、シェルは標準入力デバイスを指すのではなく、次を指すように動作します。現在の作業ディレクトリから呼び出されるファイルです。file_nameSTDINSTDOUTSTDINfile_name

他の行の場合

man < file_name

manSTDINパラメータなしで(つまり空の配列)呼び出すと、何も読み込まれません。だからこの行は

man < file_name

同じ

man

たとえば、 に渡すと、 からman内容も読むことになります。コマンドラインにこのオプションを指定すると、端末から読み取った内容をすべて表示できます。だからSTDIN-l -manmanSTDIN

man -l - < file_name

manうまくいくかもしれません(ただし、単なるページャではなくファイルの入力を解析するので、ファイルの内容と表示される内容が異なる場合がありますので注意してください)。

STDINしたがって、およびコマンドライン引数を解釈する方法はSTDOUT完全にその開発者に依存します。

私の答えで状況が明確になることを願っています。

答え2

彼らは完全に異なります。コマンドライン引数は配列としてプログラムに渡され、プログラムはそれを使用して目的の操作を実行できます。 stdinは、プログラムがデータを要求する必要がある入力ストリームです。ファイルを処理するプログラムはしばしば両方をサポートすることを選択しますが、これを手動で実行する必要があります。ファイル名がコマンドライン引数として渡されたことを確認し、そうでない場合はstdinから読み込みます。

manあなたが表示する必要があるマニュアルページを見つけるためにstdinを読むことを期待しているようです。これはいつ使用しますか?標準入力を表示するという事実は、cat他のどのツールもこのように機能しないという事実のアーティファクトです。たとえば、grepファイル名を取得したりファイルから読み取ったりできますが、stdinそのファイルのデータを処理し、stdinファイル名を読み込んstdinでから開くことはできません。

xargsこの動作が本当に必要な場合は、ファイルをコマンドライン引数に変換することができます。

$ xargs man < file_name

または、通話cat内に通話を挿入してくださいman

$ man $(cat file_name)

関連情報