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


16

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

cat file_name
cat < file_name

結果は同じです

次に、私manはの形式で実行したいstdin

man < file_name

しばらくはfile_name含まれています:

# file_name
cat

ただしWhat manual page do you want?、executeではなくポップアップし man catます。

なぜ引数としてcat受け入れるstdinことがmanできるができないのかを知りたい。そして、コマンドライン引数との違いは何stdinですか?

回答:


21

あなたの質問は、使用しているシェルがコマンドラインでのユーザー入力をどのように解析するかに密接に関連しています。

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

呼び出すプログラムは、引数(配列にある)をどのように解釈するかは、プログラムの方法によって異なります。引数の構文がどのように見えるかについての準標準がいくつかありますが、一般的にプログラマは完全に自由です。したがって、最初の引数は、ファイルの名前、またはプログラマーがプログラムを作成したときに考えていたものとして解釈できます。

特殊文字<または>コマンドラインに追加する場合、シェルは、プログラムに渡される配列に単語を追加<>たり、後続の単語を追加したりしません。と<>シェルが基本となるカーネル(キーワードでサポートされている、空想のものを作るために開始します与えられた配管)。何を理解しなければならないあなたに何が起こっているかを把握するために、STDINそしてSTDOUT(すぐに私は省略関連していないので、STDERR)です。

端末に表示されるすべてのもの(ほとんどの場合、ディスプレイの一部)は、シェルまたは以前に起動した他のプログラムによって特別なファイル(unixではすべてがファイル)に書き込まれます。このファイルには特別なIDがあり、という名前STDOUTです。プログラムがキーボードからデータを読みたい場合、キーボードを直接ポーリングするのではなく(少なくともほとんどの場合)、という特別なファイルから読み取りますSTDIN。内部的に、このファイルは標準入力デバイス、ほとんどの場合キーボードに接続されています。

シェルは、読み出した場合<、または>解析されたコマンドラインでは操作STDINSTDOUT時間のために特定の種類に対応するプログラムが実行されています。STDINまたSTDOUT、端末や標準入力デバイスを指すのではなく、コマンドラインの後続のファイル名を指すようにします。

2行の場合

cat file_name
cat < file_name

対応する開発者がcatデータの読み取りSTDINまたはファイルからのデータの読み取りを行うため、観察された動作は同じです。ファイルの名前は最初のコマンドライン引数(シェルが渡す配列の最初の要素cat)として指定されます。その後、シェルに操作を指示しないため、端末のcatコンテンツ全体file_nameまたはSTDIN端末に書き込みますSTDOUT。2行目では、シェルSTDINがこの方法で操作します。これは、もはや標準入力デバイスを指さずfile_name、現在の作業ディレクトリで呼び出されるファイルを指すことを思い出してください。

行のその他の場合

man < file_name

manSTDIN引数なしで呼び出された場合、つまり空の配列から呼び出された場合、何も読み取ることはありません。だから行

man < file_name

等しい

man

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

man -l - < file_name

また機能します(ただしman、ページャーだけでなく、ファイルの入力も解析するため、ファイルの内容と表示される内容が異なる可能性があることに注意してください)。

それでは、どのようSTDINSTDOUTコマンドライン引数が解釈されると、対応する開発者にすべてのアップです。

私の答えが問題を解決することを願っています。


この詳細な説明をありがとう。あなたの最後のいくつかの段落について、あなたは引数として解釈man -l - < file_nameするための使用について言及しましたが、私のシステムでは次のように失敗します:manSTDINSTDERRman -l - < tee man: invalid option -- l man, version 1.6c
steveyang

どういたしまして。しかし、少なくともmanman-db)のバージョンでSTDINは、指定された引数の-l後に-。からのデータをSTDINmanページとして解釈するだけです。有効な引数のより詳細な説明とその解釈方法については、関連プログラムのマニュアルページを参照する必要があります。あなたの場合に相談してくださいman man。たぶんあなたの同様のオプションがありますmanSTDIN xargs(上記のように)特定のプログラムのコマンドライン引数を読み取りたい場合は、その方法があります。
user1146332

man manは、私のOSでサポートしていないものを見つけました。とにかく、これら2つの概念を宣言してくれてありがとう。
-steveyang

lmgtfyの代わりに実際に役立つリンクが含まれるように回答を編集しました。lmgtfyリンクの投稿は、1)失礼、2)役に立たない、3)SEサイトで本当に眉をひそめています。リンクを提供するかしないかを選択しますが、そうすることを選択した場合は、実際の情報へのリンクを提供します。
テルドン

12

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

manstdinを読んで表示するmanページを見つけることを期待しているようですが、これは本当に奇妙な動作です。いつそれを使いますか?catstdin を表示するという事実は、他に何もしないという事実の成果です。他のツールがそのように機能するとは思わない。たとえばgrep、ファイル名を取得するか、から読み取ることができstdinますが、データを処理しますがstdin、ファイル名を読み取らずにstdin開きます

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

$ xargs man < file_name

または、cat呼び出し内にman呼び出しを埋め込むだけです。

$ man $(cat file_name)

bashでは、を使用できますman $(<file_name)
ヨルダン

再:「私は他のツールは、そのように動作しないと思う」 - Perlの(<>)ループで行いますSTDINか、コマンドライン引数ファイル名として...
アーロンD. Marasco

@ AaronD.Marascoツールが引数を取ることも、stdinからファイル名を読み取ることも、そのファイルから引数を読み取ることもありませんでした
Michael Mrozek

@MichaelMrozekこの説明をありがとう。私が使用した目的man < file_nameは、この2つの概念を自分で理解できるようにすることです。説明を読んで、実装はコマンドの作成者によって決定されます。私が正しい場合、find引数はむしろSTDINを処理しますか?
-steveyang
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.