私は、特定のディレクトリのファイルが最近変更されたことを確認する必要があるスクリプトを作成しています。簡単に使えると思いましたが、find
一致するものが見つからなくても成功を報告します。
$ touch afile
$ find . -mtime -1 -iname ????*
./afile
$ echo $?
0
$ find . -mtime +1 -iname ????*
$ echo $?
0
(「.」を除外するためにiname述語を使用しましたが、同じ動作-type f
)
ls
私はこのような出力を解析したくありません。性格が悪いかもしれません。。
を使用すると、test -n "$(find . -mtime -1 -iname ????*)"
期待した結果が得られるようですが、特にエレガントなソリューションではないようです。
どのファイルが変更されたかを知る必要はありません。ただ最近ファイルが変更されただけです(「最も最近」は通常1日です)。
もっと良い方法がありますか?
(Googleで検索すると、簡単な検索を実行する方法に関するSEO関連の不満がたくさんあります。)
答え1
はい、ご覧のとおり、findの終了コードを使用してこのようなことを行うことはできません。終了コードは、ファイルが見つかったかどうかではなく、コマンドが正常に実行されたかどうかに関連します。結局のところ、ファイルが見つからないのは失敗ではなく成功です。ファイルがない正しい結果が得られます。これman find
の説明は次のとおりです(GNU findから引用)。
終了ステータス
すべてのファイルが正常に処理されると、find は状態 0 で終了し、エラーが発生すると状態は 0 より大きくなります。これは意図的に非常に広範な説明ですが、戻り値がゼロでない場合は、結果の精度に依存しないでください。探す。
特定のエラーが発生すると、指定されたすべての操作を完了せずにfindがすぐに停止することがあります。たとえば、一部の始点はまだ確認されていないか、一部の保留中のプログラム呼び出しがある可能性があります。 -exec...{}+または-execdir...{}+まだ実装されていない可能性があります。
あなたは実際にそれを使用することができます-n $(find ...)
。私はそこに実際に問題を見ません。ファイル名は含めることができないため、NUL
これが壊れる可能性がある状況は考えられません。もっときちんとしたい場合は、配列を使用してから、配列の要素数を超えたかどうかをテストできます0
。このような:
$ findResults=( $(find . -mtime -1 -iname '????*' | head -n1) )
$ [[ ${#findResults[@]} -gt 0 ]] && echo "Found files!" || echo "No files found!"
Found files!
$ findResults=( $(find . -mtime +1 -iname '????*' | head -n1) )
$ [[ ${#findResults[@]} -gt 0 ]] && echo "Found files!" || echo "No files found!"
No files found!
しかし正直、これが[[ -n $(find ...) ]] && echo found || echo nope
。
答え2
zshを使用して、
if ()(($#)) **/????*(NDY1m-1); then
echo There are files or directories last modified within the last 24 hours
fi
() {body} args
定義と実行匿名関数(($#))
ここの本文は、(パラメータの数)が0以外の場合にtrueを返す算術式です。$#
**/
すべてのレベル(レベル0を含む)のディレクトリ、Extendedglobの略語です(*/)#
。それ自体は考慮されません.
。考慮したい場合**/
に置き換えることができます。{.,**/}
N
: 空のボールグローバル予選: 一致するものがなくても文句を言うのではなく、匿名関数に空のリストを渡してください。D
:dotglob、隠しファイルをスキップしないでください。Y1
: 最適化で最初の一致で停止m-1
:最後m
の修正は最後の日(24時間)で行われました(例:find
の)-mtime -1
。
を使用すると、名前が4文字以上のファイルを一致させるために代わりにset -o extendedglob
使用できます。?(#c4,)
????*
答え3
if find . -name '????*' -mtime -1 | LC_ALL=C grep -q '^'; then
echo There are files last modified within the last 24 hours
fi
一致するファイルが多い場合は、grep -q
入力行を読み込んで終了し、find
次にパイプに何かを書き込むと終了するため、少し効率的になる可能性があります。
パイプの出力はパイプに入るとバッファリングされるため、最初のファイルが見つかるとfind
パイプは終了しません。
GNUまたはFreeBSDを使用すると、find
次のことができます。
if [ -n "$(find . -name '????*' -mtime -1 -print -quit)" ]...
NetBSDでは、これはマイナーな最適化で置き換えることができる-exit
GNUを使用するのと同じです。find
-print
-printf .
次のこともできます。
if [ -n "$(
find . -name '????*' -mtime -1 -exec sh -c 'echo .; kill -s PIPE "$PPID"' ';'
)" ]...
wherefind
呼び出しはsh
何かを出力し、その親を殺します。
答え4
mtree
バイナリでいっぱいのディレクトリが悪意のあるコードや破損したコードで上書きされていないこと、またはファイルセットが誤って変更されていないことを確認したいユースケース(データまたはメタデータ)などの操作用に特別に設計されています。
-c
要約を含む目次()の参照ファイルを作成()します。my_dir.mtree
-p my_dir
-K sha256
$ sudo mtree -c -p my_dir -K sha256 > my_dir.mtree
次回ファイルが変更されたことを確認するには、パスオプションとmtree仕様ファイルのみを指定してmtree
再実行してください。-p
$ sudo mtree -p my_dir < my_dir.mtree
他のファイルがリストされます。