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
一つ追加しました。-size
chmod
ターゲットシンボリックリンクなので、シンボリックリンクを考慮することは意味がありません。あなたはおそらくさらに進んで検討したいでしょう。定期的な文書( -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
find
NULの出力を改行文字として保存しますtestfile
。ただし、このtr
コマンドはバックグラウンドで実行されることに注意してください。シェルは待ちますが(少なくともほとんどのシェルは待機しますがxargs
)、待機しません。したがって、シェルが次のコマンドを実行すると、データの書き込みがすでに完了している可能性が高くなります。それまで、書き込み全体がすべての権限を変更するよりも重要な場合は、上記とコマンドを置き換えることをお勧めします。tee
find
tr
tr
testfile
testfile
xargs
tr
別のオプションは、上記のコード全体を次のようにラップすることです。
(<that-code>) 3>&1 | cat
このようにして、シェルは、読み取り中のパイプの書き込み側でファイル記述子3が開いているすべてのプロセス(、、、、を含む)が終了した場合にのみcat
待機して終了します。cat
tr
find
tee
xargs
zsh
別のオプションはここでglobを使用することです。
files=(./*(L+100L-1000^@))
chmod a+r $files
print -rl $files > testfile
遭遇するかもしれませんがあまりにも議論するファイルのリストが大きいとエラーが発生します。find -exec +
必要にxargs
応じて、いくつかのコマンドを実行してこの問題を解決できます。これを達成するためにinを使用できます。chmod
zargs
zsh