組み込みtest
およびユーティリティは、シェルがシステムで「POSIXモード」(同じ名前の外部ユーティリティの場合でも同じ)で実行されている場合でも、ほとんど[
のシェルで-nt
(「最新」)および(「古い」)テストを持ちます. -ot
)にアクセスできます。このテストは、2つのファイルの修正タイムスタンプを比較します。それらが文書化する意味は実装ごとにわずかに異なりますが(1つまたは他のファイルが存在するか存在しない場合に発生することについて)、含まれません。POSIX仕様。test
公共施設のため。
条件付きコマンドが[KornShell]シェルから削除された場合、ユーティリティ履歴の実装に組み込まれているユーティリティには
test
まだ含まれていないため、ユーティリティに転送されません。test
sh
/bin/sh
以下のように、シェルスクリプトのファイル間の修正タイムスタンプを比較し、あるファイルが他のファイルより最新であるかどうかに応じてアクションを取るとします。
if [ "$sigfile" -nt "$timestamp" ] ||
[ "$sigfile.tmp" -nt "$timestamp" ]
then
return
fi
... make
(これはスクリプトの残りの部分が扱いにくくなることを除いて)どのような他のユーティリティを使用できますか?それとも誰も「歴史的実装」に対してスクリプトを実行しないと仮定する必要がありますか?sh
それとも、1つをあきらめる必要がありますか?特定シェルのようなbash
?
答え1
フロント:
f1=/path/to/file_1
f2=/path/to/file_2
if [ -n "$(find -L "$f1" -prune -newer "$f2")" ]; then
printf '%s is newer than %s\n' "$f1" "$f2"
fi
ファイルへの絶対パスを使用すると、ファイル名に改行のみを含む偽の肯定が防止されます。
相対パスを使用している場合は、find
コマンドを次に変更します。
find -L "$f1" -prune -newer "$f2" -exec echo . \;
答え2
これはおそらく最も古いUnixコマンドの1つですls
。
x=$(ls -tdL -- "$a" "$b")
[ "$x" = "$a
$b" ]
aがbよりも最新の場合、結果は真です。
答え3
興味深い質問をし、まず確認するべき主張をします。
次の動作を確認しました。
$shell -c '[ Makefile -nt SCCS/s.Makefile ] && echo newer'
様々なシェルで。結果は次のとおりです。
強く打つ動作しません。何も印刷されません。
ボッシュ 働く
スプリント動作しません。何も印刷されません。
クッシュ 88動作しません。何も印刷されません。
クッシュ 93 働く
ムケシ動作しません。何も印刷されません。
贅沢印刷: posh: [: -nt: 予期しない演算子/オペランド
ヤッシュ 働く
扱いにくい 最新バージョンで動作、以前のバージョンは何も印刷しません
したがって、9つのシェルのうち4つがサポートされます。-nt機能を備え、正しく実装されました。この文脈で正しい意味は次のとおりです。1秒未満のタイムスタンプ粒度をサポートする最新プラットフォームのタイムスタンプを比較する機能。私が選択したファイルのタイムスタンプは、通常数マイクロ秒程度しか異なります。
効率的な実装を見つける方が簡単なので、find
交換することをお勧めします。
if [ "$file1" -nt "$file2" ] ; then
echo newer
fi
表現に基づいていますfind
。
if [ "$( find "$file1" -newer "$file2" )" ]; then
echo newer
fi
少なくとも$file1
改行文字を含まない限り動作します。
if [ "$( find -L "$file1" -newer "$file2" -exec echo newer \; )" ]; then
echo newer
fi
少し遅いですが、うまくいきます。
ところで:ブランド情報すべてのmake実装について言うことはできませんが、SunPro Make
ナノ秒単位の時間比較は約1000000000000000000000000000000000からサポートされています。 20年後、この機能が最近追加されsmake
ましたgmake
。