ls
ファイルの内容をコマンド入力にリダイレクトしたい:
ls -l < /home/john/1.txt
コンテンツは次のように1.txt
なります:
/etc
定義されているファイル(つまりdir ls
) の内容をリストすることを想定していましたが、入力ストリームは無視されているようで、ファイルで定義されている dirではなく、現在の dir の内容がリストされます。/home/jonh1.txt
/etc
/etc
/home/jonh1.txt
答え1
入力ストリームを無視しているようです
はい。このls
プログラムは一度もない入力ストリームから何かを読み取るように書かれていないため、入力ストリームを使用します。これは、どの Unix プログラムにも自動的に付属するものではなく、別途実装する必要があります。
入力ストリーム (stdin) とコマンドライン引数 (argv) を混同しないでください。前者は行ごとに読み取ることができる実際のストリームですが、後者は単純な読み取り専用の単語配列です。この場合、両方が存在し、異なるデータが含まれています。
(なぜすべてのプログラムで自動ではないのでしょうか?選別または猫またはグレップ例として、これらのプログラムは異なる種類の値を受け入れます。ファイル名は引数として、テキストは標準入力の内容として受け入れます。したがって、任意のコマンドを にパイプすること| sort
ができ、入力がソートされます。しかし、標準入力とコマンドラインが同じものである場合、| sort
パイプ入力がファイル名のリストであると認識されるため、 に何もパイプできなくなります。またはその逆の場合、ファイル名を渡すことはできません。ファイル名がソートされるだけだからです。
別の見方については、StackOverflowのこの説明(コメントですでにお分かりですね)。
答え2
xargs を使用してみてください:
xargs ls -l < /home/john/1.txt
答え3
ユーザーからの入力を受け取るコマンドラインプログラムを書くと、何が起こっているのか非常に明確にわかるでしょう。プログラムにread/readLine(言語によって名前が異なる場合があります)ステートメントがあり、プログラムがユーザーに入力を求める場合、またはを使用してその入力をパイプまたはリダイレクトすることもできます|
。<
入力を受け取るプログラムを見ると、 またはmore
のようにless
、入力なしで入力すると$more<ENTER>
、入力を求めるプロンプトが表示されます。データをパイプすることで、入力を求めるプロンプトが表示されなくなります。 sed をパラメータなしで実行すると$sed<ENTER>
、確かにエラーが発生し、どちらも実行できません$echo abc|sed<ENTER>
。しかし、実行すると$sed 's/a/b/'<ENTER>
、入力を求めるプロンプトが表示されます。それが が echo abc|sed 's/a/b/'<ENTER>
機能する理由です。
Hello World のような単純なプログラムでも、単語の入力を要求し、ユーザーが「abc」と入力すると「Hello abc」と表示されるような入力を受け付けるプログラムを作成すれば、このことがわかります。そのプログラムにパイプすることができます。パイプと入力のリダイレクトを機能させるために、追加のプログラミングは必要ありません。プログラムがユーザーからのキーボード入力を受け入れる場合、パイプとリダイレクトは機能し、プログラムは入力を要求しません。
答え4
編集
Kamil Maciorowski 氏が以下のコメントで指摘したように、以下は正しいやり方ではありません。
/home/john/1.txt
正確に1つのパスが含まれることが保証されている場合、必ず二重引用符で囲む必要がありますファイルに複数のパスが含まれている可能性があり、意図的に単語分割に依存している場合、これは任意のパスを提供する正しい方法ではありません。
元の投稿(悪い例)
以下を使用できます。
ls -l $(cat /home/john/1.txt)
> man bash
セクションを参照コマンド置換。