プロが教える店舗&オフィスのセキュリティ対策術

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>){
....

のように書いて逃げるところと思います。

初歩的なことで恐縮ですが、よろしくお願いします。

A 回答 (4件)

#2です。


下記の方が良いと思います。
bashtest.sh abc - def ghi
のような途中に - があるケースにも対応できる。

for arg
do
case "$arg" in
-)
while read a; do
commandx "$a"
done
;;
*)
commandx "$arg"
;;
esac
done

この回答への補足

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"

補足日時:2005/07/15 15:37
    • good
    • 0

>この場合、次のような方法でよいでしょうか。


>他に良い方法があれば、あらためて教えてください。

これでよいと思います。
あと、commandx a b c と commandx "a b c" とはcommandxの動作は同じですか?もし違うなら、最後の commandx "$c" は、 commandx $c と " " をつけないのが正解です。引数の個数が3個か、1個かの違いがあります。
    • good
    • 0
この回答へのお礼

notnotさん、何度もご回答ありがとうございました。

>もし違うなら、最後の commandx "$c" は、 commandx $c と " " をつけないのが正解です。
>引数の個数が3個か、1個かの違いがあります。

あ、なるほど! 大変勉強になりました。
これで一通りのことがすっきり出来ました。
ありがとうございました。

お礼日時:2005/07/19 09:28

・引数なしなら usage を出す


・引数があれば入力ファイルと見なしてそのファイルから読む
・引数が - なら標準入力から読む
だとすると、cat の機能を使って、

if test "$*" = ""
then echo Usage: aaaaaa bbbbb cccc
  exit 0
fi
cat "$@" |
while read a
do 読んだデータ "$a" を使う処理
done
    • good
    • 0
この回答へのお礼

ご丁寧なご回答ありがとうございました。
私の質問が曖昧だったようで、すみません。
引数やパイプで受け取るのはファイル名ではなく文字列そのものとしたかったのです。
教えていただいた方法とミックスして、結果的には次のように書きました。

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

とりあえず、やりたかったことは出来るようになりました。
ありがとうございました。

お礼日時:2005/07/13 16:22

bash自身の機能として、標準入力を取得するみたいな機能は、無かったはずです。



こういった場合、スクリプト内で、入力を最初に受け取るコマンドに対してリダイレクトするような意味合いの書き方になるはずです。
汎用的な書き方としては、readコマンドを使ったこんなやり方があります。

$ cat test2.sh
#!/bin/sh

while read line
do
echo $line
done

$ echo hogehoge | bash test2.sh
hogehoge

awkでもsedでも、入力を指定しなければ勝手に標準入力から取ろうとするので、何でもいけるはずですよ。
また、初期化処理の段階で引数処理も可能なので、引数にファイル名があったら、入力をそこからとり、無ければ標準入力を待ち受けるといった処理も可能でしょう。
    • good
    • 0
この回答へのお礼

引数無しで、Usageを出すということをしたかったため、複雑にしてしまいました。

while read の構文について、参考にさせて頂きました。

ご丁寧なご回答ありがとうございました。

お礼日時:2005/07/13 16:24

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!