2012-07-05 21 views
6

QNX (Neutrino 6.5.0) verwendet eine Open-Source-Implementierung von ksh als Shell. Viele der zur Verfügung gestellten Skripten, einschließlich der Systemstartskripts, konstruiert Verwendung wieUnterschied zwischen "Test -a-Datei" und "Test-Datei -ef-Datei"

if ! test /dev/slog -ef /dev/slog; then 
    # do something 
fi 

zu prüfen, ob ein Ressourcenmanager oder nicht im Dateisystem vorhanden ist. Ich habe gesucht und konnte nur sehr dray Erklärungen finden, die -ef prüft, um zu sehen, ob die beiden Parameter in der Tat die gleiche Datei sind. Da der angegebene Dateiname derselbe ist, scheint er sich auf die Überprüfung zu beschränken, dass die Datei existiert.

Ich habe das Verhalten von test -a und test -e überprüft (beide scheinen nach Datei Existenz jeder Art von Datei nach den verschiedenen Dokumenten, die ich gelesen habe zu überprüfen) und sie scheinen auch zu arbeiten.

Gibt es Unterschiede bei den durchgeführten Prüfungen zwischen -ef und -a/-e? Verwendet -ef eine Art von Versuch, gegen eine Race-Bedingung in der Existenz der Datei zu schützen?

+0

Es scheint, als könnte es in der Tat überprüfen, dass die Datei für zwei verschiedene stat() -Aufrufe existiert. Wird der Eintrag/dev vom Treiber/Manager (z. B. nach dem Herunterfahren) nur entfernt, wenn jemand nach seiner Existenz sucht? – jhfrontz

+0

@jhfrontz: Ich bin nicht ganz sicher, was Sie meinen, aber (als Beispiel) das/dev/slog Pseudogerät wird nur entfernt, wenn der Fahrer getötet wird, was normalerweise nicht in der Mitte des Aufrufs zu "testen" da passieren würde Es ist Teil des ersten Systemstartskripts. Im normalen Fall von/dev/slog kann ein Prozess auf das Gerät schreiben, um sich in einer Datei/Konsole/Speicher einzuloggen, und während es mit einem anderen Dateinamen enden kann, sollte das in/dev angezeigte Gerät dasselbe sein wie vor dem schreibe nach/dev/slog. – tinman

+0

Ich spekuliere, dass das Stat'ing des Gerätes einige Nebeneffekte hat (zB, den Fahrer/Manager aufzufordern, irgendeine Art von Hauswirtschaft zu machen), so wie der erste stat() Aufruf (von 'test') abgeschlossen ist, die Datei/Das Gerät wird vom Treiber entfernt/ersetzt - was dazu führt, dass der zweite stat() verschiedene Informationen erhält, die wiederum zum "Test" führen. Es ist schon eine Weile her, seit ich QNX benutzt habe, aber [die Slogger-Manpage] (http: //www.qnx.com/developers/docs/6.3.0SP3/neutrino/utilities/s/slogger.html) schlägt vor, dass es bei der Interaktion mit/dev/slog Nebenwirkungen gibt (z. B. wird die Verknüpfung aufgehoben, wenn das Protokoll gelöscht wird). – jhfrontz

Antwort

4

Die Überprüfung der strace auf Ubuntu Linux Kopie ksh zeigt keine wesentlichen Unterschiede. Ein Anruf an stat vs zwei.

$ strace test /tmp/tmp.geLaoPkXXC -ef /tmp/tmp.geLaoPkXXC 

dies zeigte:

mmap(NULL, 7220736, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f11dc80b000 
close(3)        = 0 
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
close(1)        = 0 
close(2)        = 0 

... während

$ strace test -a /tmp/tmp.geLaoPkXXC 

dies zeigte:

fstat(3, {st_mode=S_IFREG|0644, st_size=7220736, ...}) = 0 
mmap(NULL, 7220736, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6b49e2b000 
close(3)        = 0 
stat("/tmp/tmp.geLaoPkXXC", {st_mode=S_IFREG|0600, st_size=0, ...}) = 0 
close(1)        = 0 
close(2)        = 0 

One stat vs zwei.

$ ksh --version 
    version   sh (AT&T Research) 93u 2011-02-08 
1

Wir wissen nicht, wie der Code den Status genau ohne Code verwenden, wir müssen den Unterschied über den Code finden.

/* code for -ef */ 
return (stat (argv[op - 1], &stat_buf) == 0 
        && stat (argv[op + 1], &stat_spare) == 0 
        && stat_buf.st_dev == stat_spare.st_dev 
        && stat_buf.st_ino == stat_spare.st_ino); 


/* code for -e/-a */ 
    case 'a':     /* file exists in the file system? */ 
    case 'e': 
     return stat (argv[pos - 1], &stat_buf) == 0; 

Also, wenn die Namen der gleichen und zwei stat() mit dem gleichen Namen sind den gleichen Wert zurück, dann ist test -a/-e file die gleiche wie test file -ef file. Wir wissen, dass die erste Bedingung wahr ist, und wir wissen, dass die zweite Bedingung auch wahr ist aus den Kommentaren von @tinman

Verwandte Themen