ฉันขอร้องคุณออกห่างจากการขยายเชลล์ธรรมดาในcpบรรทัดคำสั่ง - การขยายเชลล์มีทุกมุมของahem "สนใจ" มุมกรณี (recursion ที่ไม่พึงประสงค์ที่เกิดจาก. และ .. , ช่องว่าง, สิ่งที่ไม่พิมพ์, hardlinks, ลิงก์สัญลักษณ์และ เป็นต้น) ใช้findแทน (มันมาในfindutilsแพ็คเกจ, ในกรณีที่คุณไม่ได้ติดตั้ง - ซึ่งจะแปลก, การกระจายทั้งหมดติดตั้งโดยค่าเริ่มต้น):
find -H /path/to/toplevel/dir/ -maxdepth 1 -name '.*' -a \( -type d -o -type f -o -type l \) -exec cp -a '{}' /path/to/destination/dir/ \;
คำอธิบายทีละขั้นตอน:
-Hจะทำให้findไม่ติดตาม symlinks (ยกเว้นว่าชื่อไดเรกทอรีระดับบนสุดที่คุณให้ไว้คือ symlink ซึ่งจะเป็นไปตาม)
/path/to/toplevel/dir/ เห็นได้ชัดว่าควรจะถูกแทนที่โดยคุณด้วยเส้นทางทำไดเรกทอรีที่โฮสต์ไฟล์การตั้งค่าและไดเรกทอรีที่คุณต้องการสำรอง
-maxdepth 1จะหยุดไม่ให้findซ้ำลงไปในไดเรกทอรีใด ๆ ที่มีชื่อขึ้นต้นด้วยจุด เราไม่ต้องการให้เงินคืนcpเราจะทำเช่นนั้นสำหรับเราเราแค่ต้องการชื่อในระดับนี้
-name '.*'บอกfindว่าเราต้องการชื่อทั้งหมดที่ขึ้นต้นด้วยจุด สิ่งนี้จะไม่ทำงานอย่างถูกต้องหากPOSIXLY_CORRECTตั้งค่าตัวแปรสภาพแวดล้อมแต่ไม่ค่อยมี (ถ้าเคย) นี่เป็นเงื่อนไขการจับคู่ครั้งแรกที่เราได้ระบุไว้
a \( ....... \)เป็นและตามด้วยเงื่อนไขที่ซับซ้อนมากขึ้นในวงเล็บ (ฉันใช้ ..... เพื่อแทนที่มันได้อธิบายไว้ด้านล่าง) เราจำเป็นต้องหลบเลี่ยงวงเล็บเนื่องจากมิฉะนั้นพวกเขาจะตีความผิด (เชลล์) โดยเชลล์ ดังนั้นแบ็กสแลชที่อยู่ข้างหน้า
-type d -o -type f -o -type lเป็นสามเงื่อนไขด้วยหรือระหว่างพวกเขา -type dจับคู่ไดเรกทอรี-type fจับคู่ไฟล์ปกติและ-type lจับคู่สัญลักษณ์ คุณสามารถเลือกสิ่งที่คุณต้องการ - ตัวอย่างเช่นหากคุณไม่ต้องการสำรองข้อมูลไดเรกทอรีการตั้งค่าให้ข้าม-type d(และ-oด้านหลังขวา)
-exec ..... \;บอกfindให้รันคำสั่งทุกครั้งที่พบการแข่งขัน จุดสิ้นสุดของคำสั่งถูกทำเครื่องหมายด้วยเครื่องหมายอัฒภาคซึ่งเราต้องหลบกลับด้วยแบ็กสแลชอีกครั้งเพื่อหลีกเลี่ยงการตีความเชลล์ ภายในบรรทัดคำสั่งนั้นคุณต้องใช้{}ตำแหน่งที่คุณต้องการให้ชื่อของการแข่งขันที่พบในปัจจุบันสิ้นสุดลง ตั้งแต่เปลือกหอยอาจตีความผิดวงเล็บปีกกาคุณควรวางไว้ใน apostrophes '{}'ในขณะที่ คำสั่งที่เราต้องการดำเนินการในกรณีนี้คือcp -a '{}' /path/to/destination/dir/(-a หมายถึงไฟล์เก็บถาวรซึ่งเกิดขึ้นซ้ำในไดเรกทอรีย่อยคัดลอก symlink เป็นลิงก์และรักษาสิทธิ์และแอตทริบิวต์เพิ่มเติมและ/path/to/destination/dir/เห็นได้ชัดว่าเป็นชื่อของไดเรกทอรีปลายทาง - แทนที่มัน)
ดังนั้นในภาษาอังกฤษธรรมดาfindบรรทัดคำสั่งนี้บอกว่า:
เริ่มต้นที่ / path / to / toplevel / dir / อย่าลงไปในไดเรกทอรีย่อยใด ๆ ค้นหาไดเรกทอรีไฟล์และ symlink ทั้งหมดที่ชื่อขึ้นต้นด้วยจุด สำหรับแต่ละสิ่งที่คุณพบพบให้คัดลอกไปยัง / path / to / destination / dir / รักษาธรรมชาติสิทธิ์และแอตทริบิวต์เพิ่มเติม
-rและ-R?