これは働きます:
if [ /a/*/b/file.asd -nt /c/d/file.asd ]; then echo "found new file"; fi
これはうまくいきません:
if [[ /a/*/b/file.asd -nt /c/d/file.asd ]]; then echo "found new file"; fi
/*/
二重括弧が使用されない理由を説明できる人はいますか?
答え1
シェルグローブパターンは、複数のパス名に拡張できます。たとえば、/a/*/b/file.asd
複数のパス名に拡張すると、実行中のテストが意味をなさなくなります。
また、シェルグローブは次のとおりです。いいえ内部に拡張されました[[ ... ]]
。bash
マニュアルから:
[[
と間の単語に対してトークン化とパス名拡張を実行しないでください。]]
することを知っていれば特別なファイル(たとえば)を選択し、/a/x/b/file.asd
テストでそのパス名を使用します。テストを実行したい場合みんなループを使用してこのパターンに一致するパス名:
shopt -s nullglob dotglob
for pathname in /a/*/b/file.asd; do
if [[ $pathname -nt /c/d/file.asd ]]; then
printf 'found new file: %s\n' "$pathname"
fi
done
パターンが一致しない場合は、パターンを削除して隠しディレクトリをキャプチャするオプションを設定してnullglob
シェルします。dotglob
*
find
また、パターンが/a/*/b/file.asd
何千ものパス名に拡張されていない限り、テストを実行できます。
find /a/*/b/file.asd -prune -type f -newer /c/d/file.asd
これにより、パターンが拡張され、/a/*/b/file.asd
拡張された各パス名が検索パスとして使用されますfind
。検索パスをテストし/c/d/file.asd
、ファイルより最新の場合はパス名を印刷します。ディレクトリを参照している場合に備えて、検索パスの下に移動しないでください-prune
。find