2012-07-05 129 views
6

QNX(Neutrino 6.5.0)使用ksh的開源實現作爲其外殼。許多提供的腳本,包括系統啓動腳本中,使用語句如「測試-a文件」和「測試文件-ef文件」之間的區別

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

檢查資源管理器是否在文件系統中存在與否。我搜索過,只能找到非常有用的解釋,-ef檢查兩個參數是否實際上是相同的文件。由於指定的文件名是相同的,它似乎只是減少檢查文件存在。

我已經檢查了test -atest -e(根據我讀過的各種文檔檢查是否存在任何文件類型的文件)的行爲,並且它們似乎也可以工作。

-ef-a/-e之間執行的檢查有任何區別嗎?是否使用-ef某種方式來防止文件存在的競爭條件?

+0

它似乎確實可以檢查文件是否存在兩個不同的stat()調用。只有在有人檢查其存在時,驅動程序/管理員才能刪除/ dev條目(例如關閉後)? – jhfrontz 2012-07-11 22:21:35

+0

@jhfrontz:我不完全確定你的意思,但是(作爲例子)/ dev/slog僞設備只在驅動程序被終止時纔會被刪除,而這通常不會在調用'test'的過程中發生,因爲它是初始系統啓動腳本的一部分。在/ dev/slog的正常情況下,進程可以寫入設備以記錄到文件/控制檯/內存,並且儘管它可能以不同的文件名結束,但在/ dev中暴露的設備應該與寫入/ dev/slog。 – tinman 2012-07-11 22:47:16

+0

我在推測stat'ing設備有一些副作用(例如,提示驅動程序/管理器做某種內務),這樣當第一個stat()調用(來自'test')完成時,文件/設備被驅動程序刪除/替換 - 從而導致第二個stat()獲取不同的信息,從而導致'test'失敗。自從我使用過QNX以來,已經有一段時間了,但是[slogger man page](http://www.qnx。com/developers/docs/6.3.0SP3/neutrino/utilities/s/slogger.html)表明有與/ dev/slog交互的副作用(例如,取消鏈接它清除日誌)。 – jhfrontz 2012-07-11 23:27:33

回答

4

在Ubuntu Linux的副本ksh上查看strace沒有發現實質性差異。一個電話stat vs兩個。

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

表明這一點:

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 

...而

$ strace test -a /tmp/tmp.geLaoPkXXC 

表明這一點:

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 

一個stat VS兩項。

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

我們不知道代碼如何在沒有代碼的情況下使用統計數據,我們需要通過代碼找到差異。

/* 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; 

所以,如果名字都具有相同的名稱將返回相同的值相同的兩個統計(),然後, test -a/-e file是一樣的test file -ef file。我們知道第一個條件是真實的,並且我們知道第二個條件也是真實的,來自@tinman的評論