シェル変数を使用したコマンドの実行

シェル変数を使用したコマンドの実行

変数にunixコマンドがあります。

cmd="find /path/to/webpage -type f | grep -v .svn | xargs grep $@"
`$cmd`
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

$cmdBashスクリプトでコマンドを実行しようとすると機能しません。ただし、同じコマンドをコピーして貼り付けると機能します。何が間違っているのか教えてもらえますか?

パスの周りに引用符を入れようとしましたが、同じエラーが発生しました。

cmd="find \"/path/to/webpage\" -type f | grep -v .svn | xargs grep $@"
find: paths must precede expression
Usage: find [-H] [-L] [-P] [path...] [expression]

パラメータを削除すると、-type f次のエラーが発生します。

cmd="find /path/to/webpage | grep -v .svn | xargs grep $@"
find: invalid predicate `-v'

これによりパイプが認識されないようです。動作させるにはどうすればよいですか?

ベストアンサー1

他の人はそれを行う方法を説明しました。ここで何が起こっているのか説明します。|変数が拡張されると、パイプ文字はパイプを形成せず、リテラル文字として機能します。したがって、find次のパラメーターを使用して実行します。

{"/path/to/webpage", "-type", "f", "|", "grep", "-v", ".svn", "|", ...}

をパスとして解釈|し、式(-type f)の前に現れるべきだと文句を言います。

`$cmd`もう一つの大きな間違いは、それを唯一のコマンドラインとして使用することです。$cmd(つまりfind ...)成功し、同様の出力を生成すると、rm -rf /ユーザーの代わりに実行されます。データをコードとして扱うときは注意してください!

改善 1. find ... | grep -v ...出力から何かを除外する悪い方法です。find名前付きサブディレクトリ全体を移動し、.svn行が作成されますが、後で削除されます。ただ私にfind言わなければならないのか?

find path -type f | grep -v .svn                # don't do this
find path -name .svn -prune -o -type f -print   # do this instead

改善 2.findandを組み合わせるときは、xargs常に-print0infind-0inを使用してくださいxargs

find path ... -print0 | xargs -0 -r grep ...    # I'd also recommend -r

または正確にこれを行うこともできますgrep

grep --recursive --exclude-dir=.svn pattern path

おすすめ記事