検索:ネストされたコマンドでは、現在のファイル名がNULLと評価されます。

検索:ネストされたコマンドでは、現在のファイル名がNULLと評価されます。

サイズに応じて、ディレクトリ内のイメージセットの名前を変更しようとします。これを行うには、Imagemagikのコマンドを使用して段階的にコマンドを作成していますidentify。現在使用中ですが、出力が正確になったら切り替えるecho予定です。mvecho

find * -type f -exec echo "$(identify -format '%w-%h' {})" \;

これにより、空行がたくさん出力されます。しかし、エコなしで直接実行してみると、

find * -type f -exec identify -format '%w-%h' {} \;

予想通りサイズが出力されます。内部コマンドが正常に実行されないのはなぜですか?

答え1

拡張するには、内部に何が入っているのかecho分からないからです。この場合、モードで使用する必要があることを理解してください。{}exec{}sh -c

find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '{}' \;

答え2

使用:

find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh {} \;

説明する

問題はbashが変数を拡張する方法にあります。

find * -type f -exec echo "$(identify -format '%w-%h' {})" \;

まず、bashはサイドのコンテンツを拡張します$(...)

find * -type f -exec echo 'identify: unable to open image `{}': No such file or directory...' \;

この時点で、findはかなり役に立たない引数を持つすべてのコマンドに対して同じexecステートメントを使用します。あなたが望むのは、execの中のbash拡張を抑制することです。コンテンツを一重引用符で囲むことで、bashがコンテンツを拡張するのを防ぎます。

find * -type f -exec echo '$(identify -format %w-%h {})' \;

しかし、ここでは拡張は完全に消えました。次の式を実行して再注入できます。sh -c

find * -type f -exec sh -c 'echo "$(identify -format %w-%h {})"' \;

{}これをシェルスクリプトに配置すると、ファイル名のスペース、引用符、またはシェル特殊文字を処理するときに予期しないエラーが発生する可能性があります。この問題を解決するには、{}asパラメータをshに移動する必要があります。

find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh {} \;

詳しくは、この質問/回答をご覧ください。

最後に、で置き換えて、現在のディレクトリで自分でファイルを見つけるようにすることができます*(隠しファイルを含み、で始まるファイル名については失敗しません.)。find-

また、コマンドのデバッグを支援するために実行されたコンテンツを印刷する-xフラグを追加することもできます。これは多くのファイルで非常にうるさいことがあります。sh

関連情報