ค้นหาเจ้าของไดเรกทอรีหรือไฟล์ แต่เพียงคืนค่านั้นและไม่มีอะไรอื่น


62

ฉันกำลังมองหาคำสั่งที่จะส่งคืนเจ้าของไดเรกทอรีและเฉพาะที่ - เช่น regex แยกls -latคำสั่งหรือสิ่งที่คล้ายกัน? ฉันต้องการใช้ผลลัพธ์ในสคริปต์อื่น

คำตอบ:


102

stat จากcoreutils ของ GNUสามารถทำได้:

stat -c '%U' /path/of/file/or/directory

น่าเสียดายที่มีหลายเวอร์ชันstatและมีความสอดคล้องกันไม่มากนักในไวยากรณ์ ตัวอย่างเช่นใน FreeBSD มันจะเป็น

stat -f '%Su' /path/of/file/or/directory

ถ้าพกพาเป็นกังวลคุณอาจดีกว่าการใช้ข้อเสนอแนะ Gilles ของการรวมและls awkต้องเริ่มต้นสองกระบวนการแทนหนึ่ง แต่มีข้อได้เปรียบของการใช้ฟังก์ชันมาตรฐาน POSIX เท่านั้น:

ls -ld /path/of/file/or/directory | awk '{print $3}'

2
สถิติ -c% U / เส้นทางถ้าความกะทัดรัดเป็นโบนัส
tsvallender

1
นั่นถือว่า GNU stat ซึ่งไม่ใช่กรณีของระบบ Linux รุ่นเก่า (แม้ในระบบที่ใหม่กว่าที่ฉันจะระวังอาจมีความแตกต่างstat(มาตรฐานทั่วทั้งไซต์) ใน/usr/local/binหรือที่อื่น ๆ ในบ้านของผู้ใช้) และไม่ค่อยมี ในเรื่องอื่น ๆ
Gilles

1
stat -c %Uมีข้อได้เปรียบของการทำงานกับBusyBoxเช่นกันหากstatคำสั่งนั้นได้รับการคอมไพล์แล้ว
Gilles

1
นีซ, ตัวอย่างที่ผ่านมา (LS) ทำงานทั้งบน Unix / OSX และ Linux
kenorb

1
โปรดทราบว่า ls จะพิมพ์ uid หากไม่มีผู้ใช้ในพื้นที่ที่ตรงกับเจ้าของ (เช่นบนเครือข่ายที่ใช้ร่วมกัน) แต่stat -c '%U' DIRจะพิมพ์UNKNOWNซึ่งมีประโยชน์น้อยกว่าหรือเหมาะสมกว่าขึ้นอยู่กับว่าคุณดูอย่างไร
พื้นฐาน 6

18

การแยกเอาท์พุทของlsไม่ค่อยเป็นความคิดที่ดีแต่การได้รับสองสามฟิลด์แรกนั้นเป็นข้อยกเว้นมันใช้งานได้จริงกับ "ดั้งเดิม" ทุก unices (มันไม่ทำงานบนแพลตฟอร์มเช่นการใช้งาน Windows บางประเภทที่อนุญาตให้มีช่องว่างในชื่อผู้ใช้)

ls -ld /path/to/directory | awk 'NR==1 {print $3}'

อีกทางเลือกหนึ่งคือการใช้statคำสั่ง แต่ปัญหาstatจากเชลล์คือมีหลายคำสั่งที่มีไวยากรณ์แตกต่างกันดังนั้นstatในเชลล์สคริปต์จะไม่สามารถย้ายได้ (แม้ในการติดตั้ง Linux)

โปรดทราบว่าการทดสอบว่าผู้ใช้ที่กำหนดเป็นเจ้าของนั้นเป็นข้อเสนอที่แตกต่างกันหรือไม่

if [ -n "$(find . -user "$username" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by $username."
fi
if [ -n "$(find . -user "$(id -u)" -print -prune -o -prune)" ]; then
  echo "The current directory is owned by the current user."
fi

มีบางคนที่มีคำเตือนที่มีls | awkวิธีการที่น่าเสียดายมากเกินไปในขณะที่ผมเคยตั้งข้อสังเกตที่นี่ ฉันยังไม่ได้หาวิธีแก้ปัญหาสำหรับ "เป้าหมายไฟล์ / dir เป็น symlink ด้วยชื่ออื่น" ปัญหาที่ฉันพูดถึงในความคิดเห็นล่าสุดของฉัน
บี

แทนที่จะfind . -user "$username" -print -prune -o -pruneทำอย่างfind . -maxdepth 0 -user "$username"
Niklas Holm

@Gilles มีเหตุผลอะไรที่คุณใช้awk 'NR==1 {print $3}'แทนที่จะawk '{print $3}'ใช่ไหม? ฉันไม่แน่ใจว่าทำไมจึงNR==1จำเป็นที่นี่
Harold Fischer

1
@HaroldFischer เฉพาะในกรณีที่ขอบที่มีเส้นทางขึ้นบรรทัดใหม่ มันไม่ค่อยจำเป็น แต่ไม่เป็นอันตราย
Gilles

@Gilles ดีมากที่รู้ !! แค่อยากรู้อยากเห็นคุณรู้หรือไม่ว่าการใช้lsบรรทัดใหม่ในเส้นทางทำให้เส้นแบ่งออกเป็นสองส่วน (ซึ่งฉันเชื่อว่าเป็นกรณีขอบที่คุณพยายามครอบคลุม) ที่ GNU ls(รุ่นค่อนข้างใหม่) BusyBox lsและ FreeBSD lsขึ้นบรรทัดใหม่ถูกส่งกลับเป็น$'\n', ?และ?ตามลำดับ
Harold Fischer

9

ท่านสามารถทำได้ด้วย GNU พบ:

find $directoryname -maxdepth 0 -printf '%u\n'

นี่ไม่ใช่แบบพกพานอกระบบ GNU แต่ฉันประหลาดใจที่พบการกระจาย Linux ที่ใช้งานไม่ได้


1
สิ่งนี้ใช้ได้กับทุกระบบ Linux ที่ไม่ได้ฝังตัวและอื่น ๆ (เช่น Cygwin) ระบบฝังตัวมีแนวโน้มว่าจะมีBusyboxซึ่งfindไม่มี-printfอยู่
Gilles

อย่างที่ฉันพูดระบบ GNU
mattdm

ระบบที่ไม่มี coreutils ของ GNU (เช่น FreeBSD) ไม่มี-printf:-(.
pevik

@pevik ใช่อย่างที่ฉันพูดไป แต่คุณสามารถติดตั้ง GNU ได้ถ้าคุณต้องการ :)
mattdm

. @mattdm:. ไม่เคย :-( ที่สำคัญที่สุดเมื่อคุณเขียนสคริปต์ที่ควรจะเป็นแบบพกพา
pevik

2

ในทุบตีบริสุทธิ์คุณสามารถแปลงผลลัพธ์ของlsการอาร์เรย์และดัชนีลงในมัน

# (lrwxr-xr-x, 1, myuser, staff, 36, Oct, 21, 16:36, /path/to/file)    
file_meta=($(ls -ld /path/to/file))
file_owner="${file_meta[2]}" # myuser

มันไม่ได้เป็นสง่างามกับการใช้stat, findหรือawkแต่สามารถทำงานในหยิก

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