私の問題(を使用したスクリプト内#!/bin/sh
)は次のとおりです。アーカイブのために、ディレクトリ内のすべてのファイルをチェックサムしようとします。すべてのファイル名を含むチェックサム(私の場合はsha1)ファイルは、同じディレクトリに存在する必要があります。~/test
ファイルf1
とf2
:を含むディレクトリがあるとします。
mkdir ~/test
cd ~/test
echo "hello" > f1
echo "world" > f2
今チェックサムを計算します
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum
まさに私が望むことをします、それは現在のディレクトリのすべてのファイルのみをリストし、sha1合計を計算します(maxdepthは後で変更されるかもしれません)。STDOUTの出力は次のとおりです。
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
残念ながら、これをファイルに保存しようとすると
find -maxdepth 1 -type f -printf '%P\n' | xargs shasum > sums.sha1
結果のファイルには、それ自体のチェックサムが表示されます。
da39a3ee5e6b4b0d3255bfef95601890afd80709 sums.sha1
f572d396fae9206628714fb2ce00f72e94f2258f f1
9591818c07e900db7e1e0bc4b884c945e6a61b24 f2
shasum --check
最後の合計を保存するときにファイルをさらに変更する明らかな問題があるため、後で失敗します。
周りを見て、の-p
フラグを使用xargs
して、findコマンドを実行する前に出力ファイルが何らかの形で作成されることがわかりました。そのため、追加のファイルが見つかり、チェックサムされます...
回避策として、チェックサムを別の場所(を介して一時ディレクトリmktemp
)に保存したり、findから除外したりできることを知っていますが、なぜそのように動作するのかを理解したいと思います。たとえば、最初のコマンドが出力ファイルがすでにディスク上にあるかどうかを確認する場合、正しい答えは得られません...
sh
呼び出しが必要な場合でも、動作することは保証されていません。$0
beforeの引数が必要なことに注意してください{}
。
tee
は消えましたか?私はそれを試してみましたが、うまく機能しました1>/dev/null
。また、を追加してSTDOUTを抑制しました。答えに何か問題がありましたか、それともバグですか?
xargs
ではなく、コマンドが実行される前に最初にシェルがすべての入力、出力、パイプをリダイレクトするため、このファイルを作成するのはシェル自体ですfind
。-exec
代わりに使用してくださいfind -maxdepth 1 -type f -exec sh -c 'shasum "$@" > sums.sha1' {} +