execで-ifコマンドを見つける

execで-ifコマンドを見つける

私は現在のディレクトリの下のすべてのディレクトリとファイルを一覧表示し、次を使用してファイルかディレクトリであるかを書きたいと思います。

find -exec echo `echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi` \;

私はそれが愚かなコマンドであることを知っているか、-type fまたは他の同じコマンドを使用できますが、-type dそのコードスニペットが期待どおりに機能しない理由を理解したいと思います。ただディレクトリをすべて印刷します。たとえば、出力は次のようになりますfind

.
./dir
./dir/file

私のコードの出力は次のとおりです

. : directory
./dir : directory
./dir/file : directory

そして出力

echo `echo dir/file : ;if [ -f dir/file ]; then echo file; else echo directory;fi`

はい

dir/file : file

研究しUbuntu 14.10て使用しています。find (GNU findutils) 4.4.2

ベストアンサー1

まず、コードスニペットがコマンドを実行します。

echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi

コマンド置換を評価するには出力が必要なためです。というファイルがないため、{}出力が生成されます。

{} :
directory

findその後、コマンドは-exec、、、およびパラメータを使用して実行されるため、各ファイルのファイル名の後にスペースとが表示されますecho{}:directory: directory

echo {} :; …実際に望むのは、で見つかったすべてのファイルに対してシェルフラグメントを実行することですfind。このコードスニペットはコマンドラインからデータを受け取るため、開始されたシェルではfindなく作成されたシェルで実行する必要があります。したがって、実行中のシェルに次のように指示する必要があります。findfindfind

find -exec sh -c 'echo {} : ;if [ -f {} ]; then echo file; else echo directory;fi' \;

これは良いですが、まだ正しいではありません。ファイル名に特殊文字が含まれていない場合、一部(すべてではない)実装では機能しますが、findシェルスクリプトにファイル名を挿入するため、ファイル名が任意のシェルコマンドを実行できるようにします。$(rm -rf /)すると、コマンドがrm -rf /実行されます。ファイル名をスクリプトに渡すには、別の引数として渡します。

最初はechoコロンの後に改行文字を印刷します。これを避けるにはecho -n(シェルがサポートしている場合)またはを使用してください。printf

find -exec sh -c 'printf "%s :" "$0"; if [ -f "$0" ]; then echo file; else echo directory; fi' {} \;

-exec … {} +より高速なシェル呼び出しのグループ化を使用できます。

find -exec sh -c 'for x; do printf "%s :" "$x"; if [ -f "$x" ]; then echo file; else echo directory; fi; done' _ {} +

おすすめ記事