ฉันจะได้รับการอนุญาตแบบฐานแปดจากบรรทัดคำสั่งได้อย่างไร


373

มีคำสั่งchmodเพื่อตั้งค่าการอนุญาตไฟล์ แต่ฉันจะได้รับการอนุญาตไฟล์ในโหมดเลขฐานแปด (เช่น 755) จากบรรทัดคำสั่งหรือไม่


2
สำหรับคนอย่างฉันที่บังเอิญมาถึงหน้านี้ แต่จริงๆแล้วกำลังค้นหาวิธีการทำเช่นนี้บน Mac: stackoverflow.com/a/14855227/470749
Ryan

2
stat --format "%A" $FILEให้drwxr-x---รูปแบบที่มนุษย์อ่านได้ ซึ่งอาจมีหรือไม่มีประโยชน์
เทรเวอร์บอยด์สมิ ธ

คำตอบ:


535

คุณสามารถลอง

stat -c "%a %n" *

แทนที่*ด้วยไดเรกทอรีที่เกี่ยวข้องหรือชื่อไฟล์ที่แน่นอนที่คุณต้องการตรวจสอบ

จากหน้าคนของสถิติ ,

-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

การใช้งาน:

  • ด้วยไฟล์:

    $ stat -c "%a %n" ./Documents/Udev.html 
    664 ./Documents/Udev.html
    
  • ด้วยโฟลเดอร์:

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

(อ้างอิง)


57
บน mac os ให้ใช้stat -f '%A %a %N' *(เครดิต: geeklog.adamwilson.info/article/58/… )
s2t2

1
หากคุณรู้สึกสบายใจกับls:for f in $(ls -a); do stat -c "%a %n" $f; done;
usandfriends

2
@usandfriends การวนลูปในผลลัพธ์lsเป็นความคิดที่ไม่ดี หากคุณต้องการใช้การวนซ้ำคุณสามารถทำได้for f in *; do stat "%a %n" "$f"; done
Tom Fenech

1
ทำไมทุกสิ่งบน mac os เปลี่ยนไปเล็กน้อย (แม้ใน unix iso utils)? มีเหตุผลที่แท้จริงของสิ่งนี้หรือไม่?
Vassilis

2
กรุณา @hackel บอกเราว่าคุณรู้สึกอย่างไร ฮ่า ๆ!
MikeSchinkel

44

สิทธิ์ไฟล์ใน Linux สามารถแสดงในรูปแบบฐานแปดโดยใช้คำสั่ง Linux stat

เพียงกดCtrl+ Alt+ Tบนแป้นพิมพ์เพื่อเปิด Terminal เมื่อเปิดขึ้นให้นำทางไปยังไดเรกทอรีที่คุณต้องการค้นหาการอนุญาตของไฟล์ในโหมดฐานแปด

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

สิทธิการเข้าถึงในรูปแบบที่มนุษย์อ่านได้

% a สิทธิ์การเข้าถึงแบบเลขฐานแปด

% n ชื่อไฟล์

เลขฐานแปดและการอนุญาต

คุณสามารถใช้หมายเลขฐานแปดเพื่อแสดงโหมด / การอนุญาต:

r: 4
w: 2
x: 1

ตัวอย่างเช่นสำหรับเจ้าของไฟล์คุณสามารถใช้โหมดฐานแปดดังนี้ อ่านเขียนและดำเนินการ (เต็ม) ได้รับอนุญาตในไฟล์ในแปดคือ 0 + r + w + x = 0 + 4 + 2 + 1 = 7

สิทธิ์ในการอ่านและเขียนเฉพาะไฟล์ในรูปแปดคือ 0 + r + w + x = 0 + 4 + 2 + 0 = 6

สิทธิ์ในการอ่านและดำเนินการกับไฟล์ที่เป็นเลขฐานแปดคือ 0 + r + w + x = 0 + 4 + 0 + 1 = 5

ใช้วิธีการด้านบนเพื่อคำนวณการอนุญาตสำหรับกลุ่มและอื่น ๆ ให้เราบอกว่าคุณต้องการให้สิทธิ์แบบเต็มแก่เจ้าของอ่านและดำเนินการอนุญาตให้กลุ่มและอ่านเฉพาะสิทธิ์แก่ผู้อื่นจากนั้นคุณจะต้องคำนวณสิทธิ์ดังนี้ผู้ใช้ = r + w + x = 0 + 4 + 2 + 1 = 7 กลุ่ม = r + w + x = 0 + 4 + 2 + 0 = 6 อื่น ๆ = r + w + x = 0 + 0 + 0 + 0 + 1 = 1

การอนุญาตที่มีประสิทธิภาพคือ 761

ที่มา: http://kmaiti.blogspot.com/2011/09/umask-concept.html


2
0 เริ่มต้นแสดงถึงบิตพิเศษด้วยเช่นกัน: pastebin.com/6ymkFt71
Braiam

36

ตามรายละเอียดในการอนุญาตสไตล์“ 755” ด้วย 'ls'โดยAdam CourtemancheบนAgileAdam.comคุณสามารถสร้างนามแฝง lsoที่ทำหน้าที่เหมือนls -lแต่ประมวลผลเอาต์พุต1เล็กน้อยเพื่อแสดงสิทธิ์ในฐานแปด สิ่งนี้จะเพิ่มคอลัมน์นำที่แสดงสิทธิ์แบบฐานแปด2หลัก ตามที่เขียนไว้วิธีนี้ใช้ได้กับไฟล์และไดเรกทอรีส่วนใหญ่ แต่จะทำงานไม่ถูกต้องหากมีการตั้งค่าบิตเหนียวหรือsetuid / setgid 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}'"

นี้มีข้อบกพร่องที่ร้ายแรง แต่เป็นtechtonik ชี้ให้เห็น คุณไม่สามารถส่งผ่านอาร์กิวเมนต์ไปยังlsoนามแฝงนี้ได้เช่นเดียวกับที่คุณทำกับlsคำสั่งเนื่องจากอาร์กิวเมนต์เหล่านี้ถูกใช้เป็นอาร์กิวเมนต์เพิ่มเติมawkแทน ดังนั้นคุณจะไม่สามารถทำงานlsoบนไฟล์ที่ระบุหรือไดเรกทอรีหรือคุณสามารถส่งผ่านตัวเลือกใด ๆ (เช่น-Fหรือ--color) lsoเพื่อ


การแก้ไขคือการกำหนดlso เป็นฟังก์ชั่นมากกว่านามแฝง

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}'; }

หากคุณลองใช้การโต้ตอบในเชลล์ของคุณให้เรียกใช้unalias lsoเพื่อลบนามแฝง - คุณสามารถทำได้ก่อนหรือหลังจากที่คุณกำหนดฟังก์ชัน หากคุณใส่มันลงในไฟล์ที่มีที่มาเช่นให้~/.bashrcนำaliasบรรทัดออกมาและเพิ่มนิยามฟังก์ชัน

ทำไมจึงใช้งานได้ ซึ่งแตกต่างจากชื่อแทน, ฟังก์ชั่นเปลือกทุบตีสามารถใช้พารามิเตอร์ตำแหน่งคืออาร์กิวเมนต์บรรทัดคำสั่ง "$@"ขยายไปยังรายการอาร์กิวเมนต์เต็มรูปแบบที่ก่อให้เกิดการขัดแย้งกับฟังก์ชั่นที่จะถูกส่งผ่านไปlso ls(ไม่เหมือนกับคำจำกัดความของนามแฝงฟังก์ชันของร่างกายจะไม่ถูกยกมาดังนั้นจึงจำเป็นต้องลบ\อักขระก่อน$และ")

เนื่องจากคุณสามารถส่งตัวเลือกไปlsoเมื่อกำหนดวิธีนี้เป็นฟังก์ชั่นคุณอาจต้องการลบ-aและ-Gตัวเลือกจากคำจำกัดความ - คุณสามารถส่งต่อด้วยตนเองในกรณีที่คุณต้องการ ( ตัวเลือกที่เป็นสิ่งจำเป็นสำหรับรายละเอียดเช่นสิทธิ์ของแฟ้มที่จะแสดงที่ทุกคนจึงมีไม่มีประโยชน์ที่จะเอามัน.)-l

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}'; }

ขอบคุณtechtonik ที่ชี้ให้เห็นข้อ จำกัดในการกำหนดlsoเป็นนามแฝงดังนั้นฉันจึงกระตุ้นให้ฉันขยายโพสต์นี้ด้วยเนื้อหาเกี่ยวกับการทำให้มันเป็นฟังก์ชั่นแทน


1หนึ่งอาจทราบนี้ดูเหมือนว่าจะหยามกฎทั่วไปเกี่ยวกับการไม่แยกจากการส่งออก lslsสร้างผลลัพธ์ที่มนุษย์อ่านได้มาก สิ่งนี้นำเสนอนิสัยและข้อ จำกัด ที่ทำให้ไม่เหมาะสมสำหรับการป้อนคำสั่งอื่น ๆ ในกรณีนี้เราแยกlsตั้งแต่เราต้องการที่จะรักษาลักษณะการทำงานที่แน่นอนของการlsยกเว้นของเราเป็นหนึ่งในการเปลี่ยนแปลงเพิ่ม

2ข้อ จำกัด หนึ่งของนามแฝงนี้ซึ่งใช้กับเวอร์ชันฟังก์ชั่นที่แสดงด้านล่างและซึ่งอาจพิจารณาว่าเป็นข้อบกพร่องก็คือมันจะแสดงตัวเลขฐานแปดสามหลักเท่านั้นแม้ว่าตัวเลขฐานแปดที่สี่เป็นศูนย์ ในฐานะที่เป็นjfmercerได้ชี้ถูกต้องจากตัวเลขฐานแปดแสดงที่นี่ไม่ได้สะท้อน bit เหนียวถ้าปัจจุบันมิได้ setuid หรือ setgid บิต

3อย่างจริงจังมากขึ้นกว่าเพียงไม่แสดงหลักฐานแปดสี่คือว่าวิธีนี้ถือว่าพวกเขาจะไม่ได้ตั้งค่าและถ้าหากพวกเขา - ถ้าคุณเห็นt, sหรือSในสตริงได้รับอนุญาต - แล้วคุณควรมองข้ามตัวเลขฐานแปด เนื่องจากบิตถูกอนุมานจากสตริงสิทธิ์ในวิธีที่ไม่ได้คำนึงถึงบิต setuid / setgid เหนียว


ไม่ทำงานกับไดเรกทอรี -awk: read error (Is a directory)
Anatoly techtonik

@ techtonik ขอบคุณที่ชี้นำสิ่งนี้! ฉันได้อัปเดตคำตอบนี้เพื่อรวมการแก้ไขแล้ว
Eliah Kagan

1
คุณสามารถเพิ่ม--colorพารามิเตอร์สำหรับสีที่แสดง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
คุณค้นพบวิธีแก้ไขปัญหาเหนียว setuid / setgid ตั้งแต่โพสต์นี้หรือไม่?
Silvestris

21

เพียงขยายคำตอบที่เกี่ยวข้อง 'สถิติ' ก่อนหน้านี้ให้ง่ายขึ้น:

คุณสามารถเรียกใช้:

stat <path_to_file>

การส่งออกจะมีสิทธิ์แปดด้านพร้อมกับข้อมูลอื่น ๆ



รายละเอียด (รุ่นและตัวอย่างสถิติ):

# 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

หมายเหตุ: ( 0644 / -rw-r - r--)


6

สำหรับการพกพาคุณสามารถใช้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

หากคุณต้องการแจ้งให้ทราบเมื่อเกิดข้อผิดพลาดลอง:

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

2
นอกเหนือจากการพกพาแล้วโซลูชันของ @ cuonglm ยังแสดงอักขระแปดฐานสี่ตัวแทนที่จะเป็นสามตัวดังนั้นจึงแสดงสถานะของ "บิตเหนียว" ที่มักถูกลืม
jfmercer

2

คุณสามารถใช้findกับการ-printfกระทำ

lsไม่แสดงสิทธิ์แบบฐานแปด แต่คุณสามารถใช้findวิธีแก้ปัญหานี้ได้:

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

ตัวอย่างเช่นหากต้องการตรวจสอบไดเรกทอรีวิดีโอของฉัน:

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

ตัว%mระบุรูปแบบจะบอกให้-printfการดำเนินการพิมพ์การอนุญาตแบบฐานแปดในขณะที่ตัว%fระบุรูปแบบจะทำให้เกิดการพิมพ์ชื่อไฟล์

findคุณสามารถส่งผ่านชื่อไฟล์หลายที่ คุณสามารถใช้ globs (เช่น, find * -printf "%m:%f\n")

คุณไม่จำเป็นต้องใช้แบบทดสอบ-nameหรือ-iname; findมันเพียงพอที่จะผ่านชื่อของไฟล์หรือไดเรกทอรีที่คุณมีความสนใจในการเป็นจุดเริ่มต้นไป นั่นคือให้ชื่อของพวกเขาเป็นข้อโต้แย้งทันทีหลังจากคำfindดังที่แสดงข้างต้น

findให้คุณควบคุมวิธีการแสดงผลได้อย่างยอดเยี่ยม มีการดัดแปลงสองอย่างโดยเฉพาะที่คุณอาจพบว่ามีประโยชน์:

  • โดยค่าเริ่มต้นfindไดเรกทอรีย่อยls -Rซ้ำคล้ายกับ หากคุณไม่ต้องการfindไปที่ไดเรกทอรีย่อยของจุดเริ่มต้นที่คุณส่งไปคุณสามารถเพิ่ม-maxdepth 0(หรือใช้-maxdepthกับค่าอื่น ๆ เพื่อระบุว่าคุณต้องการไปที่ใด)

    $ find Documents -maxdepth 0 -printf "%m:%f\n"
    755:Documents
    
  • %fแสดงชื่อไฟล์เท่านั้นดังนั้นหากfindจำเป็นต้องเรียกเก็บเงินคืนเพื่อไปยังไฟล์คุณอาจไม่ทราบว่าอยู่ที่ไหน หากต้องการแสดงพา ธ ให้เริ่มต้นด้วยจุดเริ่มต้นที่พบไฟล์ใดให้ใช้%pแทน

    $ 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
    ....

ดูman findข้อมูลเพิ่มเติมเกี่ยวกับการใช้findคำสั่ง

วิธีอื่น ( lsและawk)

สิ่งนี้สามารถใช้เพื่อแสดงรายการไฟล์ไดเร็กทอรีทั้งหมดด้วยการอนุญาต:

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}'

นี่คือคำสั่งเดียวกับในนามแฝงของ Adam Courtemanchelsoซึ่งคำตอบนั้นอ้างเพียงแค่เรียกใช้เป็นคำสั่งเดียว หากคุณใช้เพียงครั้งเดียวหรือในโอกาสที่หายากคุณอาจไม่อยากเขียนมันเป็นฟังก์ชั่นนามแฝงหรือเชลล์

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.