-execdir オプションを使用した find 内で {} と + はどのように展開されるか

-execdir オプションを使用した find 内で {} と + はどのように展開されるか

findオプションを指定してプログラムを使用すると、 がディレクトリに、 がファイル名に置き換えられるという-execdir話を聞きましたが、マニュアルにはこれらが何をするのか書かれていません。これについて説明している公式ドキュメントはありますか? また、これらが相対パスまたは絶対パスとして展開されるかどうかも知りたいです。 と をパラメータとして受け取り、その内容を別々のファイルに保存するスクリプトを作成しようとしました。 これらが 2 つの別々のパラメータとして渡され、それぞれがどのように展開されるかを確認できると想定しましたが、得られた結果では 1 つのパラメータのみがスクリプトに渡されているように見えるため、これらが何であるか、どのように展開されるかをまだ完全に証明できません。{}+{}+

私が実行しているコマンドは次のとおりです:find '/home/jesse/hacking/sh_sandbox' -type f -execdir /home/jesse/hacking/sh_sandbox/save_params.sh {} +

save_params.sh スクリプトは、次のコードを含む実行可能なシェル スクリプトです。

echo $0 >> /home/jesse/hacking/sh_sandbox/zero_param.txt
echo $1 >> /home/jesse/hacking/sh_sandbox/first_param.txt
echo $2 >> /home/jesse/hacking/sh_sandbox/second_param.txt
echo $3 >> /home/jesse/hacking/sh_sandbox/third_param.txt

zero_param テキスト ファイルには、実行中のスクリプトの名前が入ります。これは予想どおりです。first_param.txt ファイルには、./filename異なるファイル名が入ります。second_param および third_param テキスト ファイルには、他のファイルと同じ行数の空白行が入ります。このことから、 に 2 番目のパラメータが渡されていないと考えられますsave_params.sh

答え1

+終了マーカーは、{}ファイル名に置き換えられ、現在のディレクトリはパスになります。

それで

  • $PWD=/home/jesse/hacking/sh_sandbox/
  • $0=/home/jesse/hacking/sh_sandbox/save_params.sh
  • $1=./zero_param.txt
  • $2=./first_param.txt
  • $3=./second_param.txt
  • $4=./third_param.txt

またはそのようなもの...質問を再度読んでみると、スクリプトは find によって検索されているディレクトリを変更するように記述されているようです。そのため、実際に何が起こるかはより複雑である可能性があります。

最初の実行ではファイルが1つしか見つかりません

  • $PWD=/home/jesse/hacking/sh_sandbox/
  • $0=/home/jesse/hacking/sh_sandbox/save_params.sh
  • $1=./save_params.sh

そのため、それを反映した内容でファイルが作成されます。

答え2

find ... -execdir command {} +そのようなことは何もしません。

コマンドを実行する前に、まず一致するファイルがあるディレクトリに変更するfind ... -exec点を除いて、とまったく同じように動作します。find

を実行しman find(または、GNU find を使用している場合は 、info findよりpinfo find詳細なドキュメントについては )、 を検索します-execdir

GNUfindマニュアルページより:

-execdir command ;

-execdir command {} +

と似ています -execが、指定されたコマンドは一致したファイルを含むサブディレクトリから実行されます。これは通常、find を開始したディレクトリではありません。一致したファイルへのパスの解決中に競合状態を回避するため、これはコマンドを呼び出すためのより安全な方法です。

アクションと同様に-exec+の形式は-execdir、複数の一致したファイルを処理するためのコマンド ラインを構築しますが、 コマンド の任意の呼び出しでは、同じサブディレクトリに存在するファイルのみがリストされます。

$PATHこのオプションを使用する場合は、環境変数が を参照しない ようにする必要があります.。そうしないと、攻撃者は を実行するディレクトリに適切な名前のファイルを残して、任意のコマンドを実行できるようになります -execdir

エントリが空の場合や絶対ディレクトリ名でない場合も同様です$PATH。find がエラーに遭遇すると、すぐに終了することがあり、保留中のコマンドがまったく実行されない場合があります。

アクションの結果は 、+ または ; バリアントのどちらが使用されているかによって異なります。-execdir command {} +は常に true を返しますが、 は -execdir command {} ;コマンドが 0 を返す場合にのみ true を返します。

マニュアルページの抜粋では言及されていませんが、 は、シェルのコマンドラインまたはスクリプトから実行される場合と;同様にエスケープする必要があります。そうしないと、シェルは をコマンドの終了として解釈しなくなり、のコマンドの終了を示す引数として に渡されることになります。 はエスケープする必要はありません。\;findfindfind-exec+

関連情報