Tôi đã thử gọi lệnh chmod theo thứ tự sai. chmod file.txt -r
Điều này làm việc vì một số lý do. chmod file.txt +r
Mặt khác từ chối làm việc. Tại sao lại thế này? Vì lý do gì mà một lệnh hoạt động, còn lệnh kia thì không?
Tôi đã thử gọi lệnh chmod theo thứ tự sai. chmod file.txt -r
Điều này làm việc vì một số lý do. chmod file.txt +r
Mặt khác từ chối làm việc. Tại sao lại thế này? Vì lý do gì mà một lệnh hoạt động, còn lệnh kia thì không?
Câu trả lời:
Đây là một cách giải thích về cách GNU chmod xử lý đầu vào và không khả dụng đối với tất cả các triển khai chmod tương thích POSIX.
Lưu ý rằng cú pháp coomand-line POSIX chmod
yêu cầu chế độ đi trước, cũng như GNUchmod
(các tùy chọn cũng phải đi trước chế độ). Bất cứ điều gì khác là một quirk thực hiện không có giấy tờ.
Bây giờ, về lý do tại sao nó xảy ra trong việc thực hiện cụ thể này:
Đó là gợi ý trong hướng dẫn :
Thông thường, mặc dù, '
chmod a-w file
' là thích hợp hơn vàchmod -w file
(không có--
) phàn nàn nếu nó hành xử khác với những gì 'chmod a-w file
' sẽ làm.
Tóm lại, các tùy chọn được phân tích cú pháp bằng getopt
tiền tố với a -
. Giống như trong ls -a
, a
là một lựa chọn. Các hình thức dài ls --all
có all
như là một tùy chọn. rm -rf
(tương đương rm -r -f
) có cả hai r
và f
tùy chọn.
Mọi thứ khác là một đối số không tùy chọn, về mặt kỹ thuật được gọi là toán hạng . Tôi thích gọi những đối số vị trí này , vì ý nghĩa của chúng được xác định bởi vị trí tương đối của chúng. Trong chmod
, đối số vị trí đầu tiên là chế độ và đối số vị trí thứ hai là tên tệp.
Tối ưu, chế độ không nên dẫn với a -
. Nếu có, bạn nên sử dụng --
để buộc phân tích cú pháp dưới dạng toán hạng thay vì tùy chọn (nghĩa là sử dụng chmod a-w file
hoặc chmod -- -w file
thay vì chmod -w file
. Điều này cũng được POSIX đề xuất .
Nếu bạn nhìn vào mã nguồn , bạn sẽ nhận thấy nó sử dụng getopt để phân tích các tùy chọn dòng lệnh. Ở đây, có cách xử lý đặc biệt cho các chế độ 'không chính xác' như -w
:
case 'r':
case 'w':
case 'x':
case 'X':
case 's':
case 't':
case 'u':
case 'g':
case 'o':
case 'a':
case ',':
case '+':
case '=':
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
/* Support nonportable uses like "chmod -w", but diagnose
surprises due to umask confusion. Even though "--", "--r",
etc., are valid modes, there is no "case '-'" here since
getopt_long reserves leading "--" for long options. */
Lấy ví dụ của bạn:
chmod a-r file.txt
sẽ là lời mời mạnh mẽ nhất .chmod +r file.txt
hoạt động vì đối số đầu tiên được hiểu theo vị trí là chế độ.chmod -r file.txt
vẫn hoạt động vì -r
được hiểu là một r
tùy chọn ngắn và đặc biệt.chmod -- -r file.txt
là chính xác và hoạt động vì -r
được hiểu theo vị trí là chế độ. Điều này khác với trường hợp không có --
bởi vì với --
sự -r
không hiểu như là một tùy chọn .chmod file.txt -r
vẫn hoạt động vì -r
được hiểu là một r
tùy chọn ngắn và đặc biệt. Tùy chọn không phụ thuộc vào vị trí. Điều này về mặt kỹ thuật lạm dụng một cách giải quyết không có giấy tờ.chmod file.txt +r
không hoạt động vì +r
toán hạng, không phải là tùy chọn. Toán hạng đầu tiên ( file.txt
) được hiểu là một chế độ ... và không thể phân tích cú pháp.getopt
lệnh , không phải là thói quen thư viện trong phần 3 . Thứ hai, đó là đề cập đến optstring
, tức là danh sách các tùy chọn được chấp nhận (trong chmod
nguồn optstring
được đặt thành "Rcfvr::w::x::X::s::t::u::g::o::a::,::+::=::"
). Phần "CHẾ ĐỘ KẾ HOẠCH" được liên kết không liên quan gì đến mảng đối số argv
có chứa các đối số được truyền vào chương trình.
a+rwx
và làm một cái gì đó giống nhưchmod * +r
, vàa+rwx
tệp sẽ xuất hiện đầu tiên trong bản mở rộng toàn cầu.