web-dev-qa-db-ja.com

find:-execの引数がありません

今日はコマンドで助けられましたが、機能していないようです。これはコマンドです:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 && rm {}\;

シェルが戻ります

find: missing argument to `-exec'

私が基本的にやろうとしているのは、ディレクトリを再帰的に調べて(他のディレクトリがある場合)、.rmファイルタイプでffmpegコマンドを実行し、.mp3ファイルタイプに変換することです。これが完了したら、変換されたばかりの.rmファイルを削除します。

これに関する助けに感謝します。

184
Abs

私は今それを理解しました。 findでexecで2つのコマンドを実行する必要がある場合、実際には2つの別々のexecが必要です。これは最終的に私のために働いた。

find . -type f -name "*.rm" -exec ffmpeg -i {} -sameq {}.mp3 \; -exec rm {} \;
52
Abs

-execコマンドは、;(シェルによる解釈を避けるために、通常\;または';'と入力する必要があります)または+で終了する必要があります。違いは、;の場合、コマンドはファイルごとに1回呼び出され、+の場合、できるだけ少ない回数だけ呼び出されることです(通常は1回ですが、コマンドラインの最大長は、すべてのファイル名で分割される可能性があります)。この例を参照してください。

$ cat /tmp/echoargs
#!/bin/sh
echo $1 - $2 - $3
$ find /tmp/foo -exec /tmp/echoargs {} \;
/tmp/foo - -
/tmp/foo/one - -
/tmp/foo/two - -
$ find /tmp/foo -exec /tmp/echoargs {} +
/tmp/foo - /tmp/foo/one - /tmp/foo/two

コマンドには2つのエラーがあります。

まず、{};を使用しますが、;は独自のパラメーターでなければなりません。

次に、コマンドは&&で終了します。 「findを実行し、成功した場合は、{};。」という名前のファイルを削除するように指定しました。 -execコマンドでシェルを使用する場合は、-exec sh -c 'ffmpeg ... && rm'などのシェルで明示的に実行する必要があります。

ただし、bashコマンド内に{}を追加しないでください。特殊文字があると問題が発生します。代わりに、-c command_stringの後に追加のパラメーターをシェルに渡すことができます(man shを参照):

$ ls
$(echo damn.)
$ find * -exec sh -c 'echo "{}"' \;
damn.
$ find * -exec sh -c 'echo "$1"' - {} \;
$(echo damn.)

最初の例では、$がシェルによって評価されていることがわかります。 $(rm -rf /)というファイルがあると想像してください:-)

(補足:-は必要ありませんが、コマンドの後の最初の変数は変数$0に割り当てられます。これは通常、実行されるプログラムの名前を含む特別な変数で、パラメータは少し汚れていますが、おそらくここでは害を及ぼすことはないので、-に設定し、$1で開始します。)

したがって、コマンドは次のようになります

find -exec bash -c 'ffmpeg -i "$1" -sameq "$1".mp3 && rm "$1".mp3' - {} \;

しかし、より良い方法があります。 findはandおよびorをサポートしているため、find -name foo -or -name barなどの操作を行うことができます。ただし、これは-execでも機能し、コマンドが正常に終了した場合はtrue、そうでない場合はfalseと評価されます。この例を参照してください。

$ ls
false  true
$ find * -exec {} \; -and -print
true

コマンドが正常に実行された場合にのみ印刷を実行しますが、trueに対しては実行されますが、falseに対しては実行されません。

したがって、-andでチェーンされた2つのexecステートメントを使用でき、前者が正常に実行された場合にのみ後者を実行します。

312
Marian

各\の前にスペースを入れてみてください。

作品:

find . -name "*.log" -exec echo {} \;

機能しない:

find . -name "*.log" -exec echo {}\;
47
Dustin Cowles

ご参考まで:
Cygwinシステム(WindowsでエミュレートされたUNIX)で「find -exec」コマンドを使用したところ、セミコロンの前のバックスラッシュを削除する必要があるようです。
find ./ -name "blabla" -exec wc -l {} ;

7
Dominique

また、他の誰かが「find:-execへの引数が見つからない」場合、これは役立つかもしれません:

一部のシェルでは、エスケープを行う必要はありません。つまり、「;」の前に「\」は必要ありません。

find <file path> -name "myFile.*" -exec rm - f {} ;
2
sellmaurer

Amazon Opsworks Chef bashスクリプトで同様の「-exec argsの欠落」が見られる場合に備えて、\をエスケープするために別のバックスラッシュを追加する必要がありました。

bash 'remove_wars' do
  user 'ubuntu'
  cwd '/'
  code <<-EOH
    find /home/ubuntu/wars -type f -name "*.war" -exec rm {} \\;
  EOH
  ignore_failure true
end
2
John Cooper

逃げる必要があると思います。

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i {} \-sameq {}.mp3 \&\& rm {}\;
1
Matthew Smith

{}と&&の両方は、コマンドラインによって展開されるため問題を引き起こします。私は試してみることをお勧めします:

find /home/me/download/ -type f -name "*.rm" -exec ffmpeg -i \{} -sameq \{}.mp3 \; -exec rm \{} \;
0
VeeArr