• ベストアンサー

findのexecdir内でパイプを使う

現在シェルスクリプトを書いています。findの-execdirの中で次のコマンドを実行したいのですが、パイプをうまく取り扱ってもらうにはどうすればよろしいでしょうか。 tail -n +$[`sed -n "/^###END_OF_SCRIPT###$/{=;q;}" $0` + 1] $0 | tar xf - よろしくお願いします。

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

  • ベストアンサー
  • trapezium
  • ベストアンサー率62% (276/442)
回答No.2

> また、-execdirを使っているのは、検索で見つかったファイルと同一の階層に展開を行うためです。 そういうことなら find . -name foo | while read i; do (cd "${i%/*}" && tail -n +$((`sed -n "/^###END_OF_SCRIPT###$/{=;q;}" $0` + 1)) $0 | tar xf -); done とかでしょう。IFS= もした方がいいかもしれない。 > 最後に、sh -cを使うと、$0はスクリプトのパスではなくなってしまいます。^^; それか export arg=$0 として ${arg} を参照するとかでしょうか。 > ちなみに、$[]でも動きました。(bashのバージョンなどによる違い?) *BSD で単にシェルスクリプトというと /bin/sh を指します。そして *BSD の /bin/sh は bash ではありません。$[] は bash の方言というか、ある意味迷惑な代物なので、通常でも $(()) を使う方がいいと思います。 ついでに補足すると sed の {=;q;} の ; も伝統的な実装では、改行を代りに使う必要があります。 {= q } みたいに。

inshin
質問者

お礼

trapeziumさん、ご教示いただきまして、ありがとうございます。 cd "${i%/*}" && tail -n +$((`sed -n "/^###END_OF_SCRIPT###$/{=;q;}" $0` + 1)) $0 | tar xf - 先にcdしてからだと、$0が相対パスの場合、動きませんでしたので、この部分を次のようにしたらうまくいきました。 tail -n +$((`sed -n "/^###END_OF_SCRIPT###$/{   =   q }" "$0"` + 1)) "$0" | tar xCf "${i%/*}" - 確かにおっしゃる通り、bashはシステム上にある数少ないGNU由来のもののうちの一つでした。迂闊でした。 ありがとうございました。

すると、全ての回答が全文表示されます。

その他の回答 (1)

  • trapezium
  • ベストアンサー率62% (276/442)
回答No.1

sh -c 経由でやるか、別スクリプトの呼び出しにするかでしょう。$0 をターゲットに置換すればいいなら、多分こんな感じ find . -name foo -execdir sh -c 'tail -n +$((`sed -n "/^###END_OF_SCRIPT###$/{=;q;}" {}` + 1)) {} | tar xf -' \; それと $[] じゃなく $(()) です。普通 $[] では演算できません。引用符の使い方に注意が必要でしょう。

inshin
質問者

お礼

trapeziumさん、ご回答いただきまして、ありがとうございます。 すみません、詳しく説明していませんでした。 まず、 tail -n +$[`sed -n "/^###END_OF_SCRIPT###$/{=;q;}" $0` + 1] $0 | tar xf - このコマンドについてですが、これは実行中のスクリプトファイル内の###END_OF_SCRIPT###に続くバイナリを特定のディレクトリに展開するためのものです。 よって、$0はスクリプトのパスになりますので、{}で置換えすることはできません。 また、-execdirを使っているのは、検索で見つかったファイルと同一の階層に展開を行うためです。 最後に、sh -cを使うと、$0はスクリプトのパスではなくなってしまいます。^^; ちなみに、$[]でも動きました。(bashのバージョンなどによる違い?) http://oxdb.hateblo.jp/entry/20110621/1308658303 こちらのサイトのコメントを参考にしました。^^

すると、全ての回答が全文表示されます。

関連するQ&A