web-dev-qa-db-ja.com

POSIX shで-nt / -otテストを実行する

組み込みのtestおよび[ユーティリティには、シェルが「POSIXモード」で実行されている場合でも、ほとんどのシェルで-nt(「より新しい」)および-ot(「より古い」)テストがあります(私がアクセスできるシステム上の同じ名前)。これらのテストは、2つのファイルの変更タイムスタンプを比較するためのものです。文書化されたセマンティクスは実装間で若干異なります(一方または他方のファイルが存在しない場合に何が起こるかに関して)が、それらは testユーティリティのPOSIX仕様 には含まれていません。

これらは、testユーティリティの歴史的な実装に組み込まれているtestユーティリティに含まれていないため、[KornShell]シェルから条件付きコマンドが削除されたとき、shユーティリティに持ち越されませんでした。

/bin/shシェルスクリプト内のファイル間の変更タイムスタンプを比較し、次のように1つのファイルが他のファイルよりも新しいかどうかに応じてアクションを実行するとします

if [ "$sigfile"     -nt "$timestamp" ] ||
   [ "$sigfile.tmp" -nt "$timestamp" ]
then
    return
fi

... make(スクリプトの残りの部分を控えめに言っても扱いにくくする)を除いて、他にどのようなユーティリティを使用できますか?または、「shの歴史的な実装」でスクリプトを実行する予定がない、または固有のシェルのような記述を辞任するとは思わないbash

11
Kusalananda

POSIXLY:

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 . \;
10
cuonglm

これは、最も古いUnixコマンドの1つであるlsを使用する場合である可能性があります。

x=$(ls -tdL -- "$a" "$b")
[ "$x" = "$a
$b" ]

Aがbよりも新しい場合、結果はtrueです。

7
meuh

興味深い質問があり、最初に確認する必要がある主張をしました。

私はの行動をチェックしました:

$Shell -c '[ Makefile -nt SCCS/s.Makefile ] && echo newer'

様々な砲弾を搭載。結果は次のとおりです。

  • bash機能しません-何も印刷されません。

  • bosh機能する

  • dash機能しません-何も印刷されません。

  • ksh88機能しません-何も出力されません。

  • ksh93機能する

  • mksh機能しません-何も出力されません。

  • poshの出力:posh:[:-nt:予期しない演算子/オペランド

  • yash機能する

  • zsh新しいバージョンで機能します、古いバージョンでは何も印刷されません

したがって、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についてすべてのmake実装について話すことはできませんが、SunPro Makeは約から、ナノ秒単位の時間比較をサポートしています。 20年間、smakegmakeはこの機能を最近追加しました。

4
schily