- ベストアンサー
bashのスクリプト内で、パイプ入力を受け取るには?
bashのスクリプトで質問です。 hoge_command 何らかのコマンド bashtest.sh bashスクリプト とあるときに、 hoge_command | bashtest.sh のようにパイプでの入力をスクリプト内で受け取る方法はありますか? たとえばperlであれば、 while(<STDIN>){ .... のようにして受け取ることができると思いますが、 bashでは、どのようにすればよいでしょう。 また、bashtest.sh で、引数無しのときにUsageを出すようにしてあった場合にうまく動作しないので、 hoge_command | bashtest.sh - のように記述して受け取る方法はあるでしょうか? (同じくperlなら、 if( $ARGV[0] eq "-" ){ while(<STDIN>){ .... のように書いて逃げるところと思います。 初歩的なことで恐縮ですが、よろしくお願いします。
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
#2です。 下記の方が良いと思います。 bashtest.sh abc - def ghi のような途中に - があるケースにも対応できる。 for arg do case "$arg" in -) while read a; do commandx "$a" done ;; *) commandx "$arg" ;; esac done
その他の回答 (3)
- notnot
- ベストアンサー率47% (4900/10358)
>この場合、次のような方法でよいでしょうか。 >他に良い方法があれば、あらためて教えてください。 これでよいと思います。 あと、commandx a b c と commandx "a b c" とはcommandxの動作は同じですか?もし違うなら、最後の commandx "$c" は、 commandx $c と " " をつけないのが正解です。引数の個数が3個か、1個かの違いがあります。
お礼
notnotさん、何度もご回答ありがとうございました。 >もし違うなら、最後の commandx "$c" は、 commandx $c と " " をつけないのが正解です。 >引数の個数が3個か、1個かの違いがあります。 あ、なるほど! 大変勉強になりました。 これで一通りのことがすっきり出来ました。 ありがとうございました。
- notnot
- ベストアンサー率47% (4900/10358)
・引数なしなら usage を出す ・引数があれば入力ファイルと見なしてそのファイルから読む ・引数が - なら標準入力から読む だとすると、cat の機能を使って、 if test "$*" = "" then echo Usage: aaaaaa bbbbb cccc exit 0 fi cat "$@" | while read a do 読んだデータ "$a" を使う処理 done
お礼
ご丁寧なご回答ありがとうございました。 私の質問が曖昧だったようで、すみません。 引数やパイプで受け取るのはファイル名ではなく文字列そのものとしたかったのです。 教えていただいた方法とミックスして、結果的には次のように書きました。 if test $# -eq 0 then echo "Usage: $0 {strings|-}" exit fi case "$1" in -) while read a; do commandx "$a" done ;; *) for a in "$@"; do commandx "$a" done ;; esac とりあえず、やりたかったことは出来るようになりました。 ありがとうございました。
- you-m
- ベストアンサー率58% (190/327)
bash自身の機能として、標準入力を取得するみたいな機能は、無かったはずです。 こういった場合、スクリプト内で、入力を最初に受け取るコマンドに対してリダイレクトするような意味合いの書き方になるはずです。 汎用的な書き方としては、readコマンドを使ったこんなやり方があります。 $ cat test2.sh #!/bin/sh while read line do echo $line done $ echo hogehoge | bash test2.sh hogehoge awkでもsedでも、入力を指定しなければ勝手に標準入力から取ろうとするので、何でもいけるはずですよ。 また、初期化処理の段階で引数処理も可能なので、引数にファイル名があったら、入力をそこからとり、無ければ標準入力を待ち受けるといった処理も可能でしょう。
お礼
引数無しで、Usageを出すということをしたかったため、複雑にしてしまいました。 while read の構文について、参考にさせて頂きました。 ご丁寧なご回答ありがとうございました。
補足
notnotさん、何度もありがとうございます。 for argで回す方法について理解しました。 もともとやりたかったことに対して、正確には次のようにしたかったのですが、 %bashtest.sh a b c とやっても、 %echo a b c | bashtest.c - とやっても、 (あるいは、%echo c | bashtest.sh a b - とやっても?) bashtest.shの中では、 commandx a b c のように呼び出すようにさせる。 この場合、次のような方法でよいでしょうか。 他に良い方法があれば、あらためて教えてください。 c="" for arg do case "$arg" in -) while read a; do c="$c $a" done ;; *) c="$c $arg" ;; esac done commandx "$c"