4

以下の大雑把に作成されたスクリプトで、これらの 3 つの検索行を合理化する方法が必要です...

#!/usr/bin/bash
#
#
if [ "find /data -type f -perm 400 -print" ] ; then
    find /data -type f -perm 400 -exec echo Modifying {} \;
    find /data -type f -perm 400 -print | xargs chmod 755
else
    echo 'No files to modify'
fi
4

2 に答える 2

4

次のように変更できます。

found=$(find /data -type f -perm 400 -print -quit)

if [ "$found" ]; then
    find /data -type f -perm 400 -exec echo Modifying {} \; -exec chmod 755 {} \; 
else
    echo 'No files to modify`
fi

説明:

  • find /data -type f -perm 400 -print -quit:で許可された最初のファイルが見つかるとすぐに、ファイル名が出力され、検索がすぐに終了します。出力は変数に保存されます(したがって、「変更するファイルがありません」を出力するかどうかは後でわかります)。400/datafound
  • -exec echo Modifying {} \; -exec chmod 755 {} \;: この連鎖構文を使用して、find によって返された各結果に対して複数のコマンドを実行できます。
  • 注: 明らかに何も見つからない場合にfind戻るため、使用はここでは機能しません。0$?
于 2012-11-15T19:31:49.237 に答える
4
while read -d $'\0' file; do
    found=yes
    echo "Modifying $file"
    chmod 755 "$file"
done < <(find /data -type f -perm 400 -print0)
if [ "x$found" != "xyes" ]; then
    echo "No files found to modify"
fi

これはBash のプロセス置換機能を使用します。と同等です

find ... | while read ...

その場合を除きwhile read、サブシェルで実行されるため、外側のシェルに表示される変数を設定することはできません。代わりに、プロセス置換を使用できます。サブシェルで<(cmd)実行され、その標準出力は名前付きパイプにリダイレクトされます。cmdそのパイプの名前が外部コマンドに代入されます。

次に<、このパイプからコマンドの標準入力にリダイレクトするために使用します。while readコマンドは、区切られた各レコードを順番に読み取り、指定された名前 (fileこの場合) に値を格納します。デフォルトでreadは、改行で改行します。ほとんどのファイルでは、それで問題ありません。あなたができる:

while read file; do
    ...
done < <(find /data -type f -perm 400)

そしてそれはうまくいくでしょう。ただし、ファイル名に改行を含めることは技術的に可能であり、その場合は壊れます。-print0find への引数と への-d $'\0'引数readにより、ファイル名では無効な区切り文字としてそれぞれがヌル文字を使用します。

于 2012-11-15T19:39:46.383 に答える