คำสั่ง cp: คัดลอกโฟลเดอร์ไฟล์ใน *nix อย่างถูกต้อง

คำสั่ง cp: คัดลอกโฟลเดอร์ไฟล์ใน *nix อย่างถูกต้อง

บทความนี้จะเปิดเผยสิ่งที่ไม่ชัดเจนที่เกี่ยวข้องกับการใช้งาน สัญลักษณ์แทน เมื่อคัดลอกพฤติกรรมคำสั่งที่ไม่ชัดเจน cp เมื่อทำการคัดลอกรวมถึงวิธีการที่ช่วยให้คุณสามารถคัดลอกไฟล์จำนวนมากได้อย่างถูกต้องโดยไม่ต้องข้ามหรือหยุดทำงาน

สมมติว่าเราจำเป็นต้องคัดลอกทุกอย่างจากโฟลเดอร์ /source ไปยังโฟลเดอร์ /target

สิ่งแรกที่นึกถึงคือ:

cp /source/* /target

มาแก้ไขคำสั่งนี้ทันทีเป็น:

cp -a /source/* /target

คีย์ -a จะเพิ่มการคัดลอกแอตทริบิวต์สิทธิ์ทั้งหมดและเพิ่มการเรียกซ้ำ เมื่อไม่จำเป็นต้องทำซ้ำสิทธิ์อย่างถูกต้อง คีย์ก็เพียงพอแล้ว -r.

หลังจากการคัดลอก เราจะพบว่าไม่ได้คัดลอกไฟล์ทั้งหมด - ไฟล์ที่ขึ้นต้นด้วยจุด เช่น:

.profile
.local
.mc

และสิ่งที่คล้ายกัน

ทำไมสิ่งนี้ถึงเกิดขึ้น?

เนื่องจากไวด์การ์ดถูกประมวลผลโดยเชลล์ (bash ในกรณีปกติ) ตามค่าเริ่มต้น bash จะละเว้นไฟล์ทั้งหมดที่ขึ้นต้นด้วยจุด เนื่องจากจะถือว่าไฟล์เหล่านั้นถูกซ่อนไว้ เพื่อหลีกเลี่ยงพฤติกรรมนี้ เราจะต้องเปลี่ยนพฤติกรรม bash ใช้คำสั่ง:

shopt -s dotglob

เพื่อให้แน่ใจว่าการเปลี่ยนแปลงพฤติกรรมนี้ยังคงอยู่หลังจากการรีบูต คุณสามารถสร้างไฟล์ wildcard.sh ด้วยคำสั่งนี้ในโฟลเดอร์ /etc/profile.d (บางทีการแจกจ่ายของคุณอาจมีโฟลเดอร์อื่น)

และหากไม่มีไฟล์ในไดเร็กทอรีต้นทางเชลล์จะไม่สามารถแทนที่สิ่งใด ๆ แทนเครื่องหมายดอกจันได้และการคัดลอกจะล้มเหลวโดยมีข้อผิดพลาดเช่นกัน มีตัวเลือกสำหรับสถานการณ์นี้ failglob и nullglob. เราจะต้องตั้งค่า failglobซึ่งจะป้องกันไม่ให้คำสั่งถูกดำเนินการ nullglob จะไม่ทำงาน เนื่องจากจะแปลงสตริงด้วยไวด์การ์ดที่ไม่พบรายการที่ตรงกันเป็นสตริงว่าง (ความยาวเป็นศูนย์) ซึ่งสำหรับ cp จะทำให้เกิดข้อผิดพลาด

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

cp -a /souce/a /source/b /source/c …… /target

มีการจำกัดความยาวของบรรทัดคำสั่ง ซึ่งเราสามารถค้นหาได้โดยใช้คำสั่ง:

getconf ARG_MAX

มารับความยาวสูงสุดของบรรทัดคำสั่งเป็นไบต์:

2097152

หรือ:

xargs --show-limits

เราได้รับสิ่งที่ชอบ:

….
Maximum length of command we could actually use: 2089314
….

ดังนั้น เรามาดำเนินการโดยไม่ต้องใช้ไวด์การ์ดเลย

มาเขียนกันดีกว่า

cp -a /source /target

และที่นี่เรากำลังเผชิญกับความคลุมเครือของพฤติกรรม cp. หากไม่มีโฟลเดอร์ /target เราก็จะได้สิ่งที่ต้องการ

อย่างไรก็ตาม หากมีโฟลเดอร์เป้าหมาย ไฟล์จะถูกคัดลอกไปยังโฟลเดอร์ /target/source

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

หากโฟลเดอร์ต้นทางและปลายทางชื่อเหมือนกัน เช่น เรากำลังคัดลอกจาก /source ไปยัง /home/source เราก็สามารถใช้คำสั่ง:

cp -a /source /home

และหลังจากการคัดลอก ไฟล์ใน /home/source จะถูกเสริมด้วยไฟล์จาก /source

นี่เป็นปัญหาเชิงตรรกะ: เราสามารถเพิ่มไฟล์ในไดเร็กทอรีปลายทางได้หากโฟลเดอร์มีชื่อเหมือนกัน แต่ถ้าต่างกัน โฟลเดอร์ต้นทางจะถูกวางไว้ภายในปลายทาง วิธีคัดลอกไฟล์จาก /source ไปยัง /target โดยใช้ cp โดยไม่มีไวด์การ์ด

เพื่อหลีกเลี่ยงข้อจำกัดที่เป็นอันตรายนี้ เราใช้วิธีแก้ปัญหาที่ไม่ชัดเจน:

cp -a /source/. /target

ผู้ที่คุ้นเคยกับ DOS และ Linux เข้าใจทุกอย่างแล้ว: ภายในแต่ละโฟลเดอร์จะมี 2 โฟลเดอร์ที่มองไม่เห็น “” และ “..” ซึ่งเป็นโฟลเดอร์หลอกที่ลิงก์ไปยังไดเร็กทอรีปัจจุบันและสูงกว่า

  • เมื่อคัดลอก cp ตรวจสอบการมีอยู่และพยายามสร้าง /target/
  • มีไดเร็กทอรีดังกล่าวอยู่และเป็น /target
  • ไฟล์จาก /source จะถูกคัดลอกไปยัง /target อย่างถูกต้อง

ดังนั้น แขวนไว้ในกรอบหนาเพื่อความทรงจำของคุณหรือบนผนัง:

cp -a /source/. /target

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

ผลการวิจัย

หากคุณต้องการคัดลอก ทั้งหมด ไฟล์จากโฟลเดอร์หนึ่งไปยังอีกโฟลเดอร์หนึ่ง เราไม่ได้ใช้ไวด์การ์ด ควรใช้แทนแทน cp รวมกับจุดท้ายโฟลเดอร์ต้นทาง การดำเนินการนี้จะคัดลอกไฟล์ทั้งหมด รวมถึงไฟล์ที่ซ่อนอยู่ และจะไม่ล้มเหลวเมื่อมีไฟล์นับล้านหรือไม่มีไฟล์เลย

เล่ม

วีเอ็มสไปค์ แนะนำเวอร์ชันคำสั่งด้วยผลลัพธ์ที่คล้ายกัน:

cp -a -T /source /target

ออซ_อเล็กซ์

cp -aT /source /target

หมายเหตุ: ตัวอักษร T มีความหมาย หากคุณผสมเข้าด้วยกันคุณจะได้รับขยะที่สมบูรณ์: ทิศทางการคัดลอกจะเปลี่ยนไป
กิตติกรรมประกาศ:

  • บริษัท RUVDS.COM สำหรับการสนับสนุนและโอกาสในการเผยแพร่บนบล็อกของคุณบนHabré
  • ต่อภาพ แนวคิดสามประการ. รูปภาพมีขนาดใหญ่และมีรายละเอียดมากสามารถเปิดในหน้าต่างแยกต่างหากได้

PS กรุณาส่งข้อผิดพลาดใด ๆ ที่คุณสังเกตเห็นในข้อความส่วนตัว ฉันเพิ่มกรรมของฉันเพื่อสิ่งนี้

คำสั่ง cp: คัดลอกโฟลเดอร์ไฟล์ใน *nix อย่างถูกต้อง

ที่มา: will.com

เพิ่มความคิดเห็น