2012-07-05 31 views
6

QNX (Neutrino 6.5.0) sử dụng mã nguồn mở của ksh làm shell của nó. Rất nhiều tập lệnh được cung cấp, bao gồm cả tập lệnh khởi động hệ thống, sử dụng các cấu trúc nhưSự khác biệt giữa "test-a file" và "test file -ef file"

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

để kiểm tra xem trình quản lý tài nguyên có tồn tại hay không trong hệ thống tệp. Tôi đã tìm kiếm và chỉ có thể tìm thấy các giải thích rất rõ ràng rằng -ef kiểm tra xem liệu hai thông số có trong thực tế cùng một tệp hay không. Kể từ khi tên tập tin được chỉ định là giống như nó có vẻ chỉ cần giảm để kiểm tra xem tập tin tồn tại.

Tôi đã kiểm tra hành vi của test -atest -e (cả hai dường như kiểm tra tệp tồn tại của bất kỳ loại tệp nào theo các tài liệu khác nhau mà tôi đã đọc) và chúng dường như cũng hoạt động.

Có sự khác biệt nào trong séc được thực hiện giữa -ef-a/-e? Đang sử dụng -ef một số loại nỗ lực để bảo vệ chống lại một tình trạng chủng tộc trong sự tồn tại của tập tin?

+0

Dường như có thể kiểm tra tệp tồn tại trong hai lệnh gọi stat khác nhau. Mục nhập/dev có bị xóa bởi trình điều khiển/trình quản lý (ví dụ: sau khi bị tắt) chỉ khi ai đó kiểm tra sự tồn tại của nó không? – jhfrontz

+0

@jhfrontz: Tôi không hoàn toàn chắc chắn ý bạn là gì nhưng (ví dụ) thiết bị giả/dev/slog chỉ bị xóa khi trình điều khiển bị giết mà thường không xảy ra ở giữa cuộc gọi đến 'test' kể từ nó là một phần của kịch bản khởi động hệ thống ban đầu. Trong trường hợp bình thường của/dev/slog, một tiến trình có thể ghi vào thiết bị để đăng nhập vào một tập tin/console/bộ nhớ, và trong khi nó có thể kết thúc với một tên tập tin khác, thiết bị tiếp xúc trong/dev phải giống như trước ghi vào/dev/slog. – tinman

+0

Tôi đang suy đoán rằng stat'ing thiết bị có một số tác dụng phụ (ví dụ, nhắc người lái xe/người quản lý thực hiện một số loại dịch vụ vệ sinh) chẳng hạn như lệnh stat() đầu tiên (từ 'test') được hoàn thành, tệp/thiết bị được gỡ bỏ/thay thế bằng trình điều khiển - do đó gây ra chỉ số thứ hai() để nhận thông tin khác, lần lượt khiến 'test' thất bại. Đã một thời gian kể từ khi tôi sử dụng QNX, nhưng [trang người slogger] (http: //www.qnx.com/developers/docs/6.3.0SP3/neutrino/utilities/s/slogger.html) cho thấy có các tác dụng phụ khi tương tác với/dev/slog (ví dụ: hủy liên kết nó xóa thanh ghi). – jhfrontz

Trả lời

4

Xem lại strace trên bản sao của Ubuntu Linux ksh không có sự khác biệt đáng kể. Một cuộc gọi đến stat so với hai cuộc gọi.

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

cho thấy điều này:

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 

... trong khi

$ strace test -a /tmp/tmp.geLaoPkXXC 

cho thấy điều này:

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 

Một stat vs hai.

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

Chúng tôi không biết mã sử dụng mã chính xác như thế nào khi không có mã, chúng tôi cần tìm sự khác biệt thông qua mã.

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

Vì vậy, nếu những cái tên đều giống nhau và hai stat() có cùng tên sẽ trở lại cùng giá trị, sau đó, test -a/-e file cũng giống như test file -ef file. Chúng tôi biết điều kiện đầu tiên là đúng và chúng tôi biết điều kiện thứ hai cũng đúng với các nhận xét từ @tinman

Các vấn đề liên quan