Die integrierten test
und [
Dienstprogramme haben in den meisten Shells die Tests -nt
("neuer als") und -ot
("älter als"), auch wenn die Shell im "POSIX-Modus" ausgeführt wird (gilt auch für die gleichnamigen externen Dienstprogramme auf dem Systeme, auf die ich Zugriff habe). Diese Tests dienen zum Vergleichen von Änderungszeitstempeln für zwei Dateien. Ihre dokumentierte Semantik variiert geringfügig zwischen den Implementierungen (in Bezug darauf, was passiert, wenn die eine oder andere Datei nicht vorhanden ist), sie sind jedoch nicht in der POSIX-Spezifikation enthalten. für das test
Dienstprogramm .
Sie wurden nicht in das
test
Dienstprogramm übernommen, als der bedingte Befehl aus der [KornShell] -Shell entfernt wurde, da sie nicht in dastest
Dienstprogramm aufgenommen wurden, das in historischen Implementierungen dessh
Dienstprogramms integriert ist.
Angenommen, ich möchte den Änderungszeitstempel zwischen Dateien in einem /bin/sh
Shell-Skript vergleichen und dann Maßnahmen ergreifen, je nachdem, ob eine Datei neuer als die andere ist, wie in
if [ "$sigfile" -nt "$timestamp" ] ||
[ "$sigfile.tmp" -nt "$timestamp" ]
then
return
fi
... welches andere Dienstprogramm könnte ich verwenden, abgesehen davon make
(was den Rest des Skripts gelinde gesagt unhandlich machen würde)? Oder sollte ich einfach davon ausgehen, dass niemand das Skript jemals auf einer "historischen Implementierung von sh
" ausführen oder sich damit abfinden wird, für eine bestimmte Shell wie zu schreiben bash
?
quelle
-nt
Funktion von nichttest
in einer Weise, wie es seit ca. 1995. Sie sollten denfind
basd-Ausdruck auch dann verwenden,bash
wenn Sie korrektes Verhalten mögen.Antworten:
POSIXLY:
Die Verwendung des absoluten Pfads zu Dateien verhindert, dass ein falsches Positiv mit Dateiname nur Zeilenumbrüche enthält.
Wenn Sie einen relativen Pfad verwenden, ändern Sie den
find
Befehl in:quelle
$f1
nur Zeilenumbrüche enthält;)-exec echo x \;
oder ähnlich gearbeitet werden?-printf
wäre einfach, wenn es Standard wärefind
der Exit-Status ist unabhängig von den einzelnenfind
Rückgabetests - außer wenn möglicherweise ein Fehler bei der tatsächlichen Ausführung dieser Tests vorliegt.find
Beendet 0, auch wenn keine Dateien gefunden wurden.[ / -nt /nofile ]
mit der Implementierung variiert (aber niemals einen Fehler ausgibt).Dies könnte ein Fall für die Verwendung eines der ältesten Unix-Befehle sein
ls
.Das Ergebnis ist wahr, wenn a neuer als b ist.
quelle
-
(fehlen--
) beginnen. Sie müssten-L
es gleichwertig sein mit-nt
. Das funktioniert nicht zum Vergleichenx
und$'x\nx'
zum Beispiel.Sie haben eine interessante Frage aufgeworfen und eine Behauptung aufgestellt, die zuerst überprüft werden sollte.
Ich habe das Verhalten überprüft von:
mit verschiedenen Muscheln. Hier sind die Ergebnisse:
Bash funktioniert nicht - druckt nichts.
bosh funktioniert
Bindestrich funktioniert nicht - druckt nichts.
ksh88 Funktioniert nicht - druckt nichts.
ksh93 funktioniert
mksh Funktioniert nicht - druckt nichts.
posh druckt: posh: [: -nt: unerwarteter Operator / Operand
Yash funktioniert
zsh funktioniert in neueren Versionen , ältere Versionen drucken nichts
Vier von neun Shells unterstützen die Funktion -nt und implementieren sie korrekt. Richtig bedeutet in diesem Fall: Zeitstempel auf aktuellen Plattformen vergleichen können, die eine Zeitstempelgranularität von weniger als einer Sekunde unterstützen . Beachten Sie, dass sich die von mir ausgewählten Dateien in ihren Zeitstempeln normalerweise nur wenige Mikrosekunden unterscheiden.
Da es einfacher ist, eine funktionierende
find
Implementierung zu finden , empfehle ich, diese zu ersetzendurch einen
find
basierten Ausdruck.funktioniert mindestens so lange, wie
$file1
nicht nur Zeilenumbrüche enthalten.ist etwas langsamer, funktioniert aber richtig.
Übrigens: In Bezug auf make kann ich nicht für alle make-Implementierungen sprechen,
SunPro Make
unterstütze aber den Zeitvergleich mit der Nanosekunden-Granularität, da ca. 20 Jahre, währendsmake
undgmake
diese Funktion vor kurzem hinzugefügt.quelle
find
Implementierungen wie Busybox oder Heirloom-Toolchest haben die gleiche Einschränkung.-L
Diefind
Version muss der Version entsprechen-nt
. Es würde auch die Dateinamen nicht auf , die mit Start-
oder!
,(
...find
habenfind -f "$file"
dafür, aber es ist nicht portabel.