置換や解釈なしで文字列リテラルを変数に保存するには?

置換や解釈なしで文字列リテラルを変数に保存するには?

ディレクトリ構造を平坦化するには、次のようにします。

find . -type f -exec sh -c 'mv "{}" "./`basename "{}"`"'  \;

私のプロフィールに以下を保存したいと思います:$ FLATTEN

-exec sh -c 'mv "{}" "./`basename "{}"`"'  \;

これにより、後で実行できます。find . $FLATTEN

早すぎると解釈され、変数を保存するのに問題があります。文字列リテラルとして保存してインポートするのではなく、シェルで使用した場合にのみ解釈したいと思います。

ベストアンサー1

GNUを使用する場合は、mv次のようにする必要があります。

find . -type f -exec mv -t . {} +

他の人mv

find . -type f -exec sh -c 'exec mv "$@" .' sh {} +

{}コードを挿入しないでくださいsh。これは、ファイル名がシェルコード(`reboot`名前付きファイルを使用しようとするなど)として解釈されるため、コマンドインジェクションの脆弱性です。

quote コマンドの置換は良い点ですが、古代形式(`...`代わりに$(...))を使用しているので、内部二重引用符またはshBourne ShellまたはAT&T kshベースの実装では機能しません。(実際には矛盾"`basename "foo bar"`"(このシェルでは許可されている)と見なされ、接続されます)。"`basename "`foobar"`"

また、次のことを行うとき:

mv foo/bar bar

bar存在し、ディレクトリであれば実際にはディレクトリです。mv foo/bar bar/barそうmv -t . foo/barでなければ、mv foo/bar .そのような問題はありません。

これで、これらのパラメータ(、、、、、、、、)を変数に格納するには-exec配列変数が必要です。配列をサポートするシェルには、、、、、、、、などがあります。sh-cexec mv "$@" .sh{}+(t)cshkshbashzshrcesyashfish

ksh/bash/yashまたは以外の$FLATTEN変数を直接使用できるようにするには、合理的な配列実装を備えたシェルが必要です。また、ここではこれらのパラメータの中に空白がありません。"${FLATTEN[@]}"$FLATTEN:q(t)cshrcesfishzsh

存在するrc/ es/ zsh

FLATTEN=(-exec sh -c 'exec mv "$@" .' sh '{}' +)

存在するfish

set FLATTEN -exec sh -c 'exec mv "$@" .' sh '{}' +

その後、次のものを使用できます。

find . -type f $FLATTEN

おすすめ記事