xargsを使用した複数のコマンドの実行

xargsを使用した複数のコマンドの実行

find + xargsを使用して複数のコマンドを呼び出すことはできますか?サイズが100文字を超えるすべてのファイルを見つけようとします。 1000文字未満の場合は、権限を変更してファイルのリストをファイルに印刷します。 execを使用してこれを行うことができます。

find . -maxdepth 1 -size +100c -size -1000c -exec chmod a+r {} \; -print > testfile

しかし、xargsを使ってこれを達成する方法はありますか?

   find . -maxdepth 1 -size +100c -size -1000c -print0 | xargs -0 -I '{}' chmod a+r '{}' -print >testfile

最後の印刷は実行されないか、エラーが発生します。 xargsを使用してこれを達成する方法はありますか?

答え1

-mindepth 1これにはGNUismは必要なく(除外する必要があります)、各ファイルに対して1つずつ実行する.必要はありません。chmod

find . ! -name . -prune ! -type l -size +100c -size -1000c -print \
  -exec chmod a+r {} + >testfile

(変更しながらシンボリックリンクのサイズも確認するため、! -type l一つ追加しました。-sizechmodターゲットシンボリックリンクなので、シンボリックリンクを考慮することは意味がありません。あなたはおそらくさらに進んで検討したいでしょう。定期的な文書( -type f))

標準出力には何も出力されないので、ここでは動作しますchmod(そうでなければテストファイルに出力されます)。

より一般的にこれを防ぐには、次のことを行う必要があります。

find . ! -name . -prune ! -type l -size +100c -size -1000c -print -exec sh -c '
  exec cmd-that-may-write-to-stdout "$@" >&3 3>&-' sh {} + 3>&1 > testfile 

したがってfind、 の stdout は に移動しtestfileますが、cmd-that-may-write-to-stdoutの stdout はリダイレクト前に元の stdout に移動します (3>&1上記で保存したとおり)。

次の点に注意してください。

find . -maxdepth 1 -size +100c -size -1000c -exec chmod a+r {} \; -print > testfile

testfile成功したファイルが含まれていますchmod-print以下は別の条件です。実行されたコマンドがゼロ以外の終了状態で返された場合は成功します)-exec-exec-print-exec

使用する場合xargs(ここではGNU構文を使用)、tee置換を使用して処理できます。

 find . ! -name . -prune ! -type l -size +100c -size -1000c -print0 |
   tee >(tr '\0' '\n' > testfile) |
   xargs -r0 chmod a+r

findNULの出力を改行文字として保存しますtestfile。ただし、このtrコマンドはバックグラウンドで実行されることに注意してください。シェルは待ちますが(少なくともほとんどのシェルは待機しますがxargs)、待機しません。したがって、シェルが次のコマンドを実行すると、データの書き込みがすでに完了している可能性が高くなります。それまで、書き込み全体がすべての権限を変更するよりも重要な場合は、上記とコマンドを置き換えることをお勧めします。teefindtrtrtestfiletestfilexargstr

別のオプションは、上記のコード全体を次のようにラップすることです。

(<that-code>) 3>&1 | cat

このようにして、シェルは、読み取り中のパイプの書き込み側でファイル記述子3が開いているすべてのプロセス(、、、、を含む)が終了した場合にのみcat待機して終了します。cattrfindteexargs

zsh別のオプションはここでglobを使用することです。

files=(./*(L+100L-1000^@))
chmod a+r $files
print -rl $files > testfile

遭遇するかもしれませんがあまりにも議論するファイルのリストが大きいとエラーが発生します。find -exec +必要にxargs応じて、いくつかのコマンドを実行してこの問題を解決できます。これを達成するためにinを使用できます。chmodzargszsh

関連情報