ฉันจะทำให้ chown ทำงานซ้ำได้อย่างไร


285

ฉันมีไดเรกทอรีชื่อหนึ่งpdfsซึ่งประกอบด้วยไดเรกทอรี ย่อยและไดเรกทอรีย่อย ฉันต้องการเปลี่ยนความเป็นเจ้าของในไฟล์ PDF ทั้งหมดในโฟลเดอร์ย่อยทั้งหมด ฉันแค่ลองทำสิ่งนี้:

chown -R someuser:somegroup *.pdf

... แต่มันไม่เปลี่ยนความเป็นเจ้าของ PDF ในไดเรกทอรีย่อย มีผู้ใช้และกลุ่มอยู่

ตามหน้า man for chown, -Rควรหมายถึงการเรียกซ้ำ:

-R, --recursive
          operate on files and directories recursively

ฉันพลาดอะไรไป

คำตอบ:


292

โหมดเรียกซ้ำใช้งานได้เฉพาะกับไดเรกทอรีไม่ใช่ไฟล์ ด้วยการใช้ glob '* .pdf' เชลล์จะส่งรายการไฟล์ไปยัง chown ซึ่งจะเห็นว่าไฟล์เหล่านี้เป็นไฟล์และเปลี่ยนแปลงการอนุญาตในไฟล์ที่เห็นและนั่นคือสิ่งที่มันทำ

จำไว้ว่าในเชลล์นั้น glob จะถูกประเมินโดยเชลล์ไม่ใช่คำสั่ง หาก glob จับคู่ไฟล์จะถูกส่งไปยังคำสั่งและคำสั่งจะไม่ทราบว่ามีไฟล์ glob อยู่ (สิ่งนี้แตกต่างจากวิธีใช้พรอมต์คำสั่งของ Windows ในการทำสิ่งต่าง ๆ ) หากคุณมี dir ด้วยเนื้อหาคล้าย:

machine:$ ls -F
file1.pdf  file2.pdf  other.txt  subdir/

และคุณพิมพ์:

chown -R someuser:somegroup *.pdf

เชลล์จะสร้างรายการก่อน: file1.pdf file2.pdf

จากนั้นเรียกใช้คำสั่งของคุณ:

chown -R someuser:somegroup file1.pdf file2.pdf

ดูไม่มีไดเรกทอรีสำหรับ -R ที่จะดำเนินการ มันทำในสิ่งที่คุณถาม - เปลี่ยนความเป็นเจ้าของในสองไฟล์บนบรรทัดคำสั่งโดยไม่สนใจแฟล็ก -R ที่เล่นโวหารนั้น

ในการทำสิ่งที่คุณต้องการหากต้องการใช้ '* .pdf' เป็นรูปแบบสำหรับไดเรกทอรีและไดเรกทอรีย่อยนี้คุณสามารถใช้findซึ่งสามารถค้นหาไฟล์ที่ตรงกับรูปแบบชื่อไฟล์ (หรือ criterea อื่น ๆ อีกมากมาย) และส่งไปยังคำสั่งย่อย

find . -type f -name '*.pdf' | xargs chown someuser:somegroup

สิ่งนี้จะเริ่มใน dir ปัจจุบัน '.' เพื่อค้นหาไฟล์ (ชนิดไฟล์ f) ของรูปแบบชื่อ'*.pdf'จากนั้นส่งผ่านไปยัง xargs ซึ่งสร้างบรรทัดคำสั่งไปยัง chmod สังเกตคำพูดที่อยู่รอบ ๆ รูปแบบ'*.pdf'จำไว้ว่าเชลล์จะสร้างรูปกลมถ้าทำได้ แต่คุณต้องการรูปแบบที่ส่งผ่านfindดังนั้นคุณจำเป็นต้องอ้างอิง

เนื่องจากชื่อไฟล์อาจมีช่องว่างในนั้นคุณต้องการใช้เคล็ดลับเพื่อทำให้ชื่อไฟล์พร้อมช่องว่างปลอดภัย:

find . -type f -name '*.pdf' -print0 | xargs -0 chown someuser:somegroup

ใน bash 3 และต่ำกว่านี่คือวิธีที่คุณต้องทำ ทรงกลมที่ทรงพลังกว่ามีให้ใน bash 4 (พร้อมshopt -s globstar) และกระสุนอื่น zsh เหมือนกันโดยใช้ glob ซ้ำ**:

chown -R someuser:somegroup ./**/*.pdf

1
แก้ไขเพื่อสะท้อนให้เห็นว่าทุบตี 4 ด้วยshopt -s globstarไม่ซ้ำกลม
kojiro

@kojiro ขอบคุณ! อย่างที่คุณบอกได้ว่าฉันยังใช้ bash3 อยู่
Rich Homolka

2
ตามหน้า man ที่แสดงโดยโปสเตอร์ต้นฉบับฉันพบ chown -R ได้เปลี่ยนเจ้าของในโฟลเดอร์และไฟล์อย่างแท้จริง ไม่จำเป็นต้องค้นหา ใช้มิ้นต์ 15.
gwideman

@ gwideman ฉันรู้ว่ามันเก่า ... แต่ใช่แน่นอน -R ไม่เกิดซ้ำ OP เพิ่งมีปัญหากับการเรียกซ้ำประเภทที่เฉพาะเจาะจงส่วนขยายและ "ประเภทไฟล์เป็นไฟล์" ที่ถูกกรองอย่างใดอย่างหนึ่ง
Rich Homolka

@RichHomolka Ah OP กล่าวว่าไฟล์อยู่ในไดเรกทอรีที่ชื่อว่า 'pdf' ดังนั้นฉันคิดว่าปัญหาคือวิธีระบุ pdf เป็นไดเรกทอรีเพื่อเรียกคืนและไฟล์ทั้งหมดที่มีเป็น pdf ดังนั้นไม่จำเป็นต้องเลือกเฉพาะ แต่คุณอาจพูดถูกถ้างานคือเลือกไฟล์ pdf เท่านั้นและปล่อยให้คนอื่นไม่เปลี่ยนแปลง
gwideman

52
chown -R someuser:somegroup /your/folder/here/*

สิ่งนี้จะนำไปใช้กับไฟล์ทั้งหมดและไดเรกทอรีย่อยและไดเรกทอรีย่อยทั้งหมดของโฟลเดอร์ที่ระบุ ใช้ด้วยความระมัดระวัง


2
อย่างใดsudo chown -R user ./ทำงานให้ฉัน แต่sudo chown -R user ./*ไม่ได้
สลา

1
ฉันรู้ว่านี่เก่า แต่ถึงแม้ว่านี่จะเป็นคำตอบพาดหัว แต่ก็ไม่ได้ตอบคำถาม นี่เป็นสิ่งที่เลวร้ายยิ่งกว่า OP ที่ได้ลองไปแล้วเล็กน้อย
คนรวย Homolka

2
@ RichHomolka ถูกนำมาที่นี่เพียงเพราะชื่อคำถามฉันยินดีที่จะหาคำตอบนี้
Félix Gagnon-Grenier

@ FélixGagnon-Grenier ยุติธรรมพอสมควร หากคำตอบนี้เหมาะกับคุณฉันมีความสุขมาก แต่มันจะไม่ได้ผลสำหรับคำถามดั้งเดิม
Rich Homolka

.envนี้ดูเหมือนจะไม่ทำงานสำหรับไฟล์จุดเช่น
Ryan

14

คุณสามารถใช้findยูทิลิตี้:

find . -name '*.pdf' -exec chown someuser:somegroup {} +

*.pdfโปรดอย่าลืมคำพูดที่อยู่รอบ ๆ มิฉะนั้นเชลล์จะพยายามขยาย ซึ่งหมายความว่าเชลล์จะแทนที่*.pdfด้วยชื่อของไฟล์ PDF ทั้งหมดที่พบในไดเรกทอรีปัจจุบัน แต่นั่นไม่ใช่สิ่งที่คุณต้องการ คุณต้องการค้นหาไฟล์ PDF ที่อยู่ในไดเรกทอรีย่อย Btw: นั่นเป็นปัญหากับchownคำสั่งของคุณด้วย


1
ฉันต้องมองหาก+ลอุบายที่ประณีตสำหรับการแสดง -exec command {} +ตัวแปรของแอ็คชัน -exec นี้รันคำสั่งที่ระบุบนไฟล์ที่เลือก แต่บรรทัดคำสั่งถูกสร้างโดยการต่อท้ายชื่อไฟล์ที่เลือกแต่ละชื่อที่ท้าย จำนวนการเรียกใช้คำสั่งทั้งหมดจะน้อยกว่าจำนวนไฟล์ที่ตรงกัน บรรทัดคำสั่งสร้างขึ้นในลักษณะเดียวกับที่xargsสร้างบรรทัดคำสั่ง อนุญาตหนึ่งอินสแตนซ์ของ{}ภายในคำสั่ง คำสั่งจะถูกดำเนินการในไดเรกทอรีเริ่มต้น
Patrick M

@PatrickM หนึ่ง (เล็กน้อย) ได้เปรียบอื่นจาก + vs; .... บวกไม่ใช่ตัวอักษรเมตาของเชลล์และไม่ต้องหลบหนี
Rich Homolka

6

คำสั่ง

chown -R someuser:somegroup *.pdf

จะลดจำนวนไดเรกทอรีหากชื่อไดเรกทอรีลงท้ายด้วย. pdf คุณต้องการบางสิ่งเช่น:

find . -name "*.pdf" -exec chown someuser:somegroup {} \;

ในทางเทคนิคแล้วมันจะลดลงไปหนึ่งระดับ ไม่ว่าคุณจะเรียกว่าการเรียกซ้ำจริงหรือไม่คือการออกกำลังกายสำหรับผู้ใช้ :)
รวย Homolka

1

ในการเปลี่ยนความเป็นเจ้าของไดเรกทอรีซ้ำใช้:

sudo chown -R <username>:<groupname> <dir name>

here username = ผู้ใช้ใหม่ที่ควรเป็นเจ้าของไดเรกทอรี

groupname = กลุ่มใหม่ที่ควรเป็นเจ้าของไดเรกทอรี

ทุกไฟล์ / ไดเรกทอรีมีเจ้าของผู้ใช้และเจ้าของกลุ่ม


นี่ไม่ได้ทำในสิ่งที่ OP ถาม การเปลี่ยนแปลงนี้เป็นเจ้าของทุกสิ่ง OP ได้ขอไฟล์ชุดหนึ่งโดยเฉพาะ
Rich Homolka

0

ฉันใช้treeแทน:

 sudo tree -fai ~/.blabla  | xargs -L1 -I{} sudo chown youruser:youruser {}

นอกจากนี้โปรดระวังอย่าเรียกใช้ chown ซ้ำหรือ chmod ในไดเรกทอรี '/' หรือไดเรกทอรีระบบอื่น ๆ


0

หากต้องการเป็นเจ้าของไฟล์ทั้งหมดในไดเรกทอรีให้ใช้

find directory -type f -name '*' | sudo xargs -d '\n' chown $USER

แทน

sudo chown $USER directory\*

หรือ

sudo chown --recursive $USER directory

ซึ่งอาจไม่ทำงานหากมีข้อโต้แย้งมากเกินไปที่สร้างโดย * (ไฟล์มากเกินไปในไดเรกทอรี) หรือที่ไม่ได้ทำสิ่งที่คุณต้องการตามลำดับ

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