どちらかの形式を使用して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
がstdin
を引数として受け入れることができたが、man
は受け入れられない理由を知りたいです。そして、コマンドライン引数とstdin
の違いは何ですか?
あなたの質問は、使用しているシェルがコマンドラインでユーザー入力をどのように解析するかと密接に関連しています。
コマンドラインの最初のWordがプログラムであり、特別なフォルダー(ほとんどがPATH
で定義されている)にあり、特殊文字が指定されていない場合(使用しているシェルによって異なります)、スペースまたはタブで区切られた後続のすべての単語が渡されます特別な形式、すなわち配列でプログラムに。各Wordを配列の1つの要素として。
プログラムがどのように呼び出すかは、(配列内にある)引数をどのようにプログラムするかによって異なります。引数の構文がどのように見えるかについては準標準がいくつかありますが、一般的にプログラマーは完全に自由です。したがって、最初の引数は、ファイルの名前、またはプログラマーがプログラムを作成したときにプログラマーが考えていたものとして解釈できます。
特殊文字_<
_または_>
_をコマンドラインに追加する場合、シェルは_<
_および_>
_を追加せず、後続の単語を配列に追加しませんプログラムに渡されます。シェルが_<
_または_>
_を指定すると、基盤となるカーネル(キーワード piping )によってサポートされる、ファンシーなものを作り始めます。何が起こっているのかを把握するには、STDIN
とSTDOUT
が何であるかを理解する必要があります(直接関係がないため、STDERR
は省略しています)。
ターミナルに表示されるすべてのもの(ほとんどの場合、ディスプレイの一部)は、シェルまたは以前に起動した他のプログラムによって、特別なファイルに書き込まれます( nixすべてはファイル ) 。このファイルには特別なIDがあり、STDOUT
と呼ばれます。プログラムがキーボードからデータを読み取りたい場合、キーボードを直接ポーリングしません(少なくともほとんどの場合)が、STDIN
と呼ばれる特別なファイルから読み取ります。内部的に、このファイルは標準入力デバイス、ほとんどの場合キーボードに接続されています。
解析されたコマンドラインでシェルが_<
_または_>
_を読み取る場合、対応するプログラムが実行されている間、シェルはSTDIN
またはSTDOUT
を特定の種類で操作します。 STDIN
とSTDOUT
は、もはやターミナルや標準入力デバイスを指すのではなく、コマンドラインの後続のファイル名を指します。
2行の場合
_cat file_name
cat < file_name
_
対応する開発者がcat
にSTDIN
からデータを読み取るか、ファイルからデータを読み取るため、観測された動作は同じです。名前は、最初のコマンドライン引数(シェルがcat
に渡す配列の最初の要素)として指定されます。 。その後、シェルにcat
を操作するように指示しないため、STDIN
は_file_name
_またはSTDOUT
のコンテンツ全体をターミナルに書き込みます。 2行目で、シェルはSTDIN
をこのように操作します。これは、標準入力デバイスを指すのではなく、現在の作業ディレクトリにある_file_name
_というファイルを指すことを覚えておいてください。
ラインの他の場合
_man < file_name
_
man
は、引数なしで呼び出された場合、つまり空の配列である場合、STDIN
から何かを読み取ることを意図したものではありません。だから行
_man < file_name
_
等しい
_man
_
たとえば、_-l -
_をman
に渡すと、STDIN
もman
から何かを読み取ります。コマンドラインでこのオプションを指定すると、man
から読み取ったSTDIN
の内容を端末に表示できます。そう
_man -l - < file_name
_
(ただし、man
は単なるページャーではなく、ファイルの入力を解析するため、ファイルの内容と表示される内容が異なる可能性があるので注意してください)。
したがって、STDIN
、STDOUT
、およびコマンドライン引数の解釈方法は、すべて対応する開発者次第です。
私の答えが明らかになることを願っています。
それらは完全に異なります。コマンドライン引数は配列でプログラムに渡され、プログラムはそれらを使って必要なことを実行できます。 stdinは、プログラムがデータを要求する必要がある入力ストリームです。ファイルを処理するプログラムは多くの場合、両方をサポートすることを選択しますが、手動でサポートする必要があります。ファイル名がコマンドライン引数として渡されたかどうかをチェックし、そうでない場合は代わりにstdinから読み取ります
man
がstdinを読み取って、表示する必要のあるmanページを見つけることを期待しているようですが、これは非常に奇妙な動作です。いつそれを使用しますか? cat
がstdinを表示するという事実は、他に何もしないという事実のアーティファクトです。他のツールがそのように機能するとは思いません。たとえば、grep
はファイル名を取得するかstdin
から読み取ることができますが、stdin
のデータを処理しますが、stdin
からファイル名を読み取りませんそしてそれを開きます
この動作が本当に必要な場合は、xargs
を使用できます。これにより、ファイルがコマンドライン引数に変換されます。
$ xargs man < file_name
または、cat
呼び出し内にman
呼び出しを埋め込むだけです。
$ man $(cat file_name)