• ベストアンサー

リダイレクションで標準入力を変更できない

入門UNIXシェルプログラミングを読んで 今まで眠らせていたレッドハットのいろんな操作方法を学習しています。 今は第4章リダイレクションによるファイル操作を読み進めています。 >を使って標準出力を変更する方法を学習しました。 また、<を使って標準入力を変更する方法も学習しました。 しかし、本の例のとおりに入力しても、標準入力を変更できませんでした。 $cat xyz abc nnn $ls < xyz aaa abc nnn xyz xyzで指定したabc nnnのリストを表示させたいのに 全てのリストが表示されてしまいます。 つまり、< xyz以降が無視されて、引数なしのlsが実行されてしまいます。 他にも私が知ってるコマンド(echoやcat)でも標準入力が変更できるか試してみたのですが、やはりダメでした。 $ echo < xyz $ cat < xyz abc nnn echoは空行を表示します。 catの場合は、<だけが無視されてcat xyzとして実行されるようです。 どなたか教えてください。 このリダイレクションの使い方は合ってますよね。 どうやれば、標準入力を変更できるのですか。

質問者が選んだベストアンサー

  • ベストアンサー
  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.4

#3です。 本当に、「lsコマンドは標準入力を読む」と書いてあったのなら、正誤表に載せるどころか著者はlsコマンドを実際に使ったことが無いとしか思えないですね。 >そこで、リダイレクションを使ってキーボードからではなくファイルから入力する例を1つ挙げていただけないでしょうか。 >lsやechoやcatではリダイレクションがうまく使えないもので・・・(汗 echoは先に書いたように標準入力を読みませんから、入力のリダイレクトは無意味です。「echoのリダイレクションがうまく使えない」とお書きということはechoコマンドの働きをきちんと理解できていないと思われます。再度書きますが、標準入力を読まないコマンドに対して標準入力のリダイレクトは意味がありません(リダイレクトは出来ますが、読まれないので書かないのと同じ)。 cat の入力リダイレクトの例は、 cat < xyz です。 質問文で、「<だけが無視されて」とお書きですが、無視されているわけじゃなくて、ちゃんと標準入力がファイルxyzにリダイレクトされてxyzから読み込まれています。cat < xyz だと「< xyz」がリダイレクト指定になるので引数から取り除かれ、引数無しで起動されるので標準入力からデータを読み取ります。 cat < xyz abc だと、abc が引数となるので、ファイルabc からデータを読み込み、標準入力は読みませんから、せっかくリダイレクトしても xyz の内容は読み込まれません。このように同じcatコマンドであっても引数の有無によって標準入力を読んだり読まなかったりします。

zyousuke
質問者

お礼

notnotさん、ご返信ありがとうございます。 この本には確かにlsに渡す引数を標準入力からタイプすると書いてあります。 なので私は引数と標準入力の意味を混同していました。 notnotさんの説明で引数と標準入力の違いが良く理解できました。 cat < xyz abc を実行してみました。 catは引数がある場合は標準入力を読まないため、この場合はabcの内容が表示されるのですね。 また cat < xyz も実行してみました。 catは引数がない場合は標準入力を読むため、この場合はxyzというファイルが標準入力となり、xyzの内容が表示されるのですね。 この本の誤りをまとめると、 リダイレクションの説明をするために、たまたまlsを例として取り上げ、 lsの仕様を熟知しないまま結果を予想(確信)して記載してしまった。 その際、実際にシェルで確認しなかったので誤りに気が付かなかった。 といったところでしょうか。 ただし、この本は本場の方が書かれていますので訳者が誤った可能性も考えられますね。 本頁はリダイレクションの説明なのでとりあえずリダイレクションの使用法が正しいことと、 読者の評価も比較的高い書籍であることから、捨ててしまうとかはせずに、 ひとまず誤りの報告をして、このまま読み進めたいと思います。

その他の回答 (3)

  • notnot
  • ベストアンサー率47% (4900/10358)
回答No.3

引数と標準入力を混同しておられるようです。 リダイレクトは標準入力の切り替えであり、引数には全く関係しません。 catは引数があればそれをファイル名としてファイルオープンして読み出して標準出力に書き出すコマンド。引数がなければ標準入力を読み出して標準出力に書き出すコマンドです。 lsは引数があればそのファイルの名前や属性を表示するコマンド。引数がなければカレントディレクトリの(.で始まらない)全ファイルの名前や属性を表示するコマンドです。 echoは引数があればそれをそのまま、なければ空を標準出力に出力するコマンドです。 引数をどう扱うか、引数が無い場合の動作、標準入力をどうあつかうか等はコマンドによって異なります。 ls は標準入力を読まず、引数だけがコマンドの動作に影響を与えますので、入力をリダイレクトしても無意味です。耳の聞こえない人に話しかけるのと同じ。 xyzという名前のファイルの内容をlsの引数に与えたいなら、 ls `cat xyz` 等とします。

zyousuke
質問者

お礼

notnotさん、ご回答ありがとうございます。 今読んでる本の出版社のサイトで正誤表を確認しました。 ただし本件は正誤表には載っていないため、まだ指摘が寄せられていないと思われます。 そこで私が第一発見者として報告したいと思います。 その前に、何度もスミマセンがもう一度確認させてください。 この本によりますとlsコマンドには通常、 $ ls a b a b のようにファイル名を引数として指定できるのですが $ echo a b > filelist $ ls < filelist a b のようにキーボードからファイル名を指定するのではなく、リダイレクションを使って、ファイル名の一覧が記述されているファイルを指定することもできるそうなのです。 しかし、これは誤りで実際には、 $ ls < filelist a b filelist のように入力をリダイレクトしても、引数を指定しなかった場合と同じように全部のファイルが表示される ということでよろしいでしょうか。 cat、ls、echoの説明は私の認識と相違ありませんでした。 あと、もう1つ教えてほしいことがあります。 標準入力の変更方法がまだいまいち分かっていないと思います。 そこで、リダイレクションを使ってキーボードからではなくファイルから入力する例を1つ挙げていただけないでしょうか。 lsやechoやcatではリダイレクションがうまく使えないもので・・・(汗

回答No.2

> 標準入力からlsにファイルリストを渡せるかどうか試してみました。 「標準入力」と「コマンド引数」は別物ですよね? lsコマンドは、標準入力から何も受け取りません。 > どうやれば、標準入力を変更できるのですか 最初の質問で既に変更されてますよ。 bashのmanページによると、  < filename とすると、ファイル"filename"がオープンされて標準入力として読み込めるようになる、とあります。 一方catコマンドは、引数にファイル名が指定されない場合は標準入力から読み込みます。 ここで、ファイル xyz の内容が  abc nnn の場合、 $ cat < xyz を実行すると、「xyzがオープンされてcatコマンドの標準入力にリダイレクトされ、catコマンドは標準入力の内容を出力する」ので、結果は  abc nnn が表示されます。 "<"だけが無視されて...という訳ではなく、 $ cat xyz | cat - のようなものでしょうか。

zyousuke
質問者

お礼

tropic_snowさん、ご返信ありがとうございます。 ひょっとしたら標準入力の定義が書籍によって相違しているのかも知れません。 私が今読んでる本によると、標準入力とは入力元のことであり、デフォルトではキーボードです。 リダイレクションを使うと、この標準入力をキーボードではなくファイルに変更したりできます。 通常はlsに渡す引数はキーボードから指定するのですが、リダイレクションを使って標準入力を変更すればファイルを引数にできるのです。 なので、私が期待していた動作は次のとおりです。 $cat xyz abc nnn $ls < xyz abc nnn $echo < xyz abc nnn $cat < xyz abcの内容 nnnの内容 しかし、実際には $cat xyz abc nnn $ls < xyz aaa abc nnn xyz #全てのファイル $echo < xyz #空行 $cat < xyz abc nnn #xyzの内容 となってしまいますので、 この本が誤っている可能性も考えられます。 ちょっとリダイレクションの使い方がよく分かっていないのかも知れません。 皆さんの助言お待ちしてます。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

勘違いだったらごめんなさい。 そもそも、lsとか標準入力からファイルリストを得るようにはなっていないと思います。

zyousuke
質問者

お礼

BLUEPIXYさん、ご回答ありがとうございます。 標準入力からlsにファイルリストを渡せるかどうか試してみました。 $ ls aaa abc nnn xyz $ ls aaa aaa lsを引数なしで実行するとファイルのリストが表示されるのですが、lsに引数としてファイル名を指定すると指定したファイルだけが表示されました。 以上よりlsは標準入力からファイルリストを得るようになっていると思います。 私のリダイレクションの使い方が間違っていないのであれば、なぜ標準入力を変更できないのか原因が不明です。 標準入力の変更をやるために何かいいコマンドがあれば教えていただけないでしょうか。

関連するQ&A