変数に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]
$cmd
Bashスクリプトでコマンドを実行しようとすると機能しません。ただし、同じコマンドをコピーして貼り付けると機能します。何が間違っているのか教えてもらえますか?
パスの周りに引用符を入れようとしましたが、同じエラーが発生しました。
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.find
andを組み合わせるときは、xargs
常に-print0
infind
と-0
inを使用してくださいxargs
。
find path ... -print0 | xargs -0 -r grep ... # I'd also recommend -r
または正確にこれを行うこともできますgrep
:
grep --recursive --exclude-dir=.svn pattern path