Làm cách nào tôi có thể nhận được quyền bát phân từ dòng lệnh?


373

Có một lệnh chmod để đặt quyền truy cập tệp, nhưng tôi có thể nhận quyền truy cập tệp ở chế độ bát phân (chẳng hạn như 755) từ dòng lệnh không?


2
Đối với những người như tôi vô tình hạ cánh trên trang này nhưng thực sự đang tìm kiếm cách thực hiện điều này trên Mac: stackoverflow.com/a/14855227/470749
Ryan

2
stat --format "%A" $FILEcung cấp cho bạn drwxr-x---định dạng có thể đọc được . có thể có hoặc không hữu ích
Trevor Boyd Smith

Câu trả lời:


535

Bạn co thể thử

stat -c "%a %n" *

Thay thế *bằng thư mục có liên quan hoặc tên tệp chính xác mà bạn muốn kiểm tra.

Từ trang man của stat ,

-c  --format=FORMAT
          use  the  specified  FORMAT instead of the default; output a newline after
          each use of FORMAT
%a     Access rights in octal
%n     File name

Sử dụng:

  • Với các tập tin:

    $ stat -c "%a %n" ./Documents/Udev.html 
    664 ./Documents/Udev.html
    
  • Với các thư mục:

    $ stat -c "%a %n" ./Documents/
    755 ./Documents/
    

(Tài liệu tham khảo)


57
trên mac os, sử dụng stat -f '%A %a %N' *(tín dụng: geeklog.adamwilson.info/article/58/iêu )
s2t2

1
Nếu bạn cảm thấy thoải mái hơn với ls:for f in $(ls -a); do stat -c "%a %n" $f; done;
usandfriends 18/07/2015

2
@usandfriends lặp trên đầu ra lslà một ý tưởng tồi. Nếu bạn thực sự muốn sử dụng một vòng lặp bạn có thể làmfor f in *; do stat "%a %n" "$f"; done
Tom Fenech

1
Tại sao trên mac os mọi thứ đều thay đổi một chút (ngay cả trong unix iso utils)? Có một lý do thực sự của điều này?
Vassilis

2
Vui lòng @hackel, cho chúng tôi biết bạn thực sự cảm thấy như thế nào. cười ngả nghiêng!
MikeSchinkel

44

Quyền truy cập tệp trong Linux có thể được hiển thị ở định dạng bát phân bằng lệnh stat Linux.

Chỉ cần nhấn Ctrl+ Alt+ Ttrên bàn phím để mở Terminal. Khi nó mở ra, hãy điều hướng đến thư mục mà bạn muốn tìm các quyền của tệp ở chế độ bát phân.

stat -c '%A %a %n' *

% A Quyền truy cập ở dạng người có thể đọc được

% quyền truy cập trong bát phân

% n Tên tệp

Số bát phân và quyền

Bạn có thể sử dụng số bát phân để biểu thị chế độ / quyền:

r: 4
w: 2
x: 1

Ví dụ: đối với chủ sở hữu tệp, bạn có thể sử dụng chế độ bát phân như sau. Đọc, viết và thực thi (đầy đủ) quyền trên một tệp trong bát phân là 0 + r + w + x = 0 + 4 + 2 + 1 = 7

Chỉ cho phép đọc và viết trên một tệp trong bát phân là 0 + r + w + x = 0 + 4 + 2 + 0 = 6

Chỉ đọc và thực thi quyền trên một tệp trong bát phân là 0 + r + w + x = 0 + 4 + 0 + 1 = 5

Sử dụng phương pháp trên để tính toán quyền cho nhóm và những người khác. Giả sử bạn muốn cấp quyền đầy đủ cho chủ sở hữu, đọc và thực thi quyền cho nhóm và chỉ đọc quyền cho người khác, sau đó bạn cần tính toán quyền như sau: Người dùng = r + w + x = 0 + 4 + 2 + 1 = 7 Nhóm = r + w + x = 0 + 4 + 2 + 0 = 6 Khác = r + w + x = 0 + 0 + 0 + 1 = 1

Sự cho phép hiệu quả là 761.

Nguồn: http://kmaiti.blogspot.com/2011/09/umask-concept.html


2
Số 0 ban đầu cũng đại diện cho bit đặc biệt: pastebin.com/6ymkFt71
Braiam

36

Như được nêu chi tiết trong các quyền của kiểu 755 với các 'ls' của Adam Courtemanche trên AgileAdam.com , bạn có thể tạo một bí danh lso hoạt động giống như ls -lnhưng xử lý nhẹ đầu ra 1 để hiển thị các quyền cũng theo bát phân. Điều này thêm một cột hàng đầu hiển thị quyền hai chữ số 3 chữ số . Như đã viết, điều này hoạt động cho hầu hết các tệp và thư mục, nhưng nó không hoạt động đúng nếu các bit dính hoặc setuid / setgid được đặt. 3

alias lso="ls -alG | awk '{k=0;for(i=0;i<=8;i++)k+=((substr(\$1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(\" %0o \",k);print}'"

Điều này có một thiếu sót nghiêm trọng, mặc dù, như techtonik chỉ ra . Bạn không thể vượt qua đối số này lsobí danh như bạn sẽ đến các lslệnh , bởi vì họ đang thực hiện như là đối số bổ sung để awkthay thế. Do đó, bạn không thể chạy lsotrên một tệp hoặc thư mục cụ thể, cũng như không thể chuyển bất kỳ tùy chọn nào (như -F, hoặc --color) cho lso.


Cách khắc phục là xác định lso hàm chứ không phải bí danh.

lso() { ls -alG "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Nếu bạn đang thử tương tác trong vỏ của mình, hãy chạy unalias lsođể xóa bí danh - bạn có thể làm điều đó trước hoặc sau khi bạn xác định hàm. Nếu bạn đang đặt nó vào một tệp có nguồn gốc, chẳng hạn như ~/.bashrc, chỉ cần lấy ra aliasdòng và thêm định nghĩa hàm.

Tại sao điều này làm việc? Không giống như bí danh, các hàm bash shell có thể nhận các tham số vị trí , tức là các đối số dòng lệnh . "$@"mở rộng đến danh sách đối số đầy đủ , làm cho các đối số của lsohàm được truyền tới ls. (Không giống như một định nghĩa bí danh, một thân hàm không được trích dẫn; do đó cần phải loại bỏ các \ký tự trước $".)

Vì bạn có thể chuyển các tùy chọn lsokhi được định nghĩa theo cách này là một hàm, bạn có thể muốn xóa -a-Gcác tùy chọn khỏi định nghĩa - bạn có thể chuyển chúng theo cách thủ công trong trường hợp bạn muốn chúng. ( Các -ltùy chọn là cần thiết cho các chi tiết như cho phép file được hiển thị ở tất cả , vì vậy không có lợi cho việc loại bỏ nó.)

lso() { ls -l "$@" | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }

Nhờ techtonik cho chỉ ra những hạn chế trong việc xác định lsonhư một bí danh, do đó thúc đẩy tôi để mở rộng bài đăng này với tài liệu về làm cho nó một chức năng để thay thế.


1 Người ta có thể lưu ý điều này dường như bỏ qua quy tắc chung về việc không phân tích cú pháp đầu rals . lstạo ra đầu ra rất dễ đọc của con người; điều này giới thiệu các đặc điểm riêng và giới hạn làm cho nó thường không phù hợp làm đầu vào cho các lệnh khác. Trong trường hợp này, chúng tôi phân tích cú pháp lschúng tôi muốn duy trì hành vi chính xácls ngoại trừ một thay đổi được thêm vào của chúng tôi .

2 Một hạn chế của bí danh này, cũng áp dụng cho phiên bản hàm hiển thị bên dưới và có thể được coi là một lỗi, là nó chỉ hiển thị ba chữ số bát phân ngay cả khi chữ số bát phân thứ tư bằng không. Như jfmercer đã chỉ ra một cách đúng đắn , các chữ số bát phân hiển thị ở đây không phản ánh bit dính nếu có, cũng không phải bit setuid hoặc setgid.

3 cách nghiêm túc hơn chỉ đơn thuần là không hiển thị các chữ số bát phân thứ tư là phương pháp này giả định họ không được thiết lập, và nếu họ là - nếu bạn nhìn thấy t, shoặc Strong chuỗi sự cho phép - thì bạn nên bỏ qua các chữ số bát phân . Điều này là do các bit được suy ra từ chuỗi quyền theo cách không tính đến các bit setuid / setgid dính.


không hoạt động với các thư mục -awk: read error (Is a directory)
anatoly techtonik

@techtonik Cảm ơn bạn đã chỉ ra điều này! Tôi (cuối cùng) đã cập nhật câu trả lời này để bao gồm một bản sửa lỗi cho điều đó.
Eliah Kagan

1
Bạn có thể thêm --colortham số cho màu hiển thịlso() { ls -alG "$@" --color | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/)*2^(8-i));if(k)printf(" %0o ",k);print}'; }
tagplus5

1
Bạn đã phát hiện ra một giải pháp cho vấn đề setuid / setgid dính từ khi đăng bài này chưa?
Silvestris ngày

21

Chỉ cần mở rộng \ đơn giản hóa các câu trả lời liên quan đến 'stat' trước đó:

Bạn chỉ có thể chạy:

stat <path_to_file>

Đầu ra sẽ chứa quyền bát phân cùng với thông tin khác.



Chi tiết (phiên bản stat và ví dụ):

# stat --version
stat (GNU coreutils) 8.4


[user@localhost ~]# touch /tmp/TEST_PERMISSONS

[user@localhost ~]# chmod 644 /tmp/TEST_PERMISSONS

[user@localhost ~]# stat /tmp/TEST_PERMISSONS
  File: `/tmp/TEST_PERMISSONS'
  Size: 0           Blocks: 0          IO Block: 4096   regular empty file
Device: fd00h/64768d    Inode: 1010058     Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2015-08-26 18:58:59.000000000 +0300
Modify: 2015-08-26 18:58:59.000000000 +0300
Change: 2015-08-26 18:59:16.000000000 +0300

Lưu ý: ( 0644 / -rw-r - r--)


6

Đối với tính di động, bạn có thể sử dụng perl:

$ perl -e 'printf "%04o %s\n", (stat)[2] & 07777, $_ for @ARGV' *.txt
0644 1.txt
0644 2.txt
0644 3.txt
0644 4.txt
0600 PerlOneLiner.txt
0664 perl.txt

Nếu bạn muốn thông báo khi xảy ra lỗi, hãy thử:

perl -e '
for (@ARGV) {
    print "$!: $_\n" and next unless -e;
    printf "%03o %s\n", (stat)[2] & 07777, $_;
}
' *.txt

2
Ngoài việc có thể mang theo, giải pháp của @ cuonglm hiển thị bốn ký tự bát phân chứ không phải ba , do đó hiển thị trạng thái của "bit dính" thường bị lãng quên.
jfmercer

2

Bạn có thể sử dụng findvới các -printfhành động.

lskhông hiển thị quyền bát phân, nhưng bạn có thể sử dụng findcách giải quyết dựa trên cơ sở này :

find path -printf "%m:%f\n"

Ví dụ: để kiểm tra thư mục Video của tôi:

$ find Videos -printf "%m:%f\n"
755:Videos

Trình %mxác định định dạng cho biết -printfhành động in quyền bát phân, trong khi trình %fxác định định dạng khiến nó in tên tệp.

Bạn có thể chuyển nhiều tên tập tin đến find. Bạn thậm chí có thể sử dụng các khối (ví dụ, find * -printf "%m:%f\n").

Bạn không phải sử dụng một bài kiểm tra như -namehoặc -iname; Chỉ cần vượt qua tên của các tệp hoặc thư mục mà bạn quan tâm là điểm bắt đầu find. Đó là, cung cấp tên của họ dưới dạng đối số ngay sau từ find, như được hiển thị ở trên.

findcung cấp cho bạn quyền kiểm soát tuyệt vời về cách nó hiển thị đầu ra. Có hai sửa đổi cụ thể mà bạn có thể thấy hữu ích:

  • Theo mặc định, findđệ quy các thư mục con, tương tự như ls -R. Nếu bạn không muốn findtruy cập các thư mục con của các điểm bắt đầu mà bạn chuyển đến nó, bạn có thể thêm -maxdepth 0(hoặc sử dụng -maxdepthvới các giá trị khác để cho biết mức độ bạn muốn nó đi sâu đến đâu).

    $ find Documents -maxdepth 0 -printf "%m:%f\n"
    755:Documents
    
  • %fchỉ hiển thị tên tệp, vì vậy nếu findphải lặp lại để lấy tệp, bạn có thể không biết nó nằm ở đâu. Để hiển thị một đường dẫn, bắt đầu với bất kỳ điểm bắt đầu nào tệp được tìm thấy bên dưới, sử dụng %pthay thế.

    $ find /boot -printf "%m:%p\n"
    755:/boot
    644:/boot/initrd.img-4.4.0-92-generic
    600:/boot/System.map-4.4.0-93-generic
    600:/boot/vmlinuz-4.4.0-92-generic
    600:/boot/vmlinuz-4.4.0-93-generic
    ....

Xem man findđể biết thêm thông tin về việc sử dụng findlệnh.

Phương pháp khác ( lsawk)

Điều này có thể được sử dụng để liệt kê tất cả các tệp thư mục với quyền của họ:

ls -l | awk '{k=0;for(i=0;i<=8;i++)k+=((substr($1,i+2,1)~/[rwx]/) \
             *2^(8-i));if(k)printf("%0o ",k);print}'

Đây thực chất là lệnh tương tự như trong bí danh của Adam Courtemanchelso , câu trả lời được trích dẫn, chỉ chạy như một lệnh duy nhất. Nếu bạn chỉ sử dụng điều này một lần hoặc trong một dịp hiếm hoi, thì bạn có thể không muốn viết nó dưới dạng bí danh hoặc hàm shell.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.