มีข้อเสียของการตั้งค่า 'noclobber' หรือไม่?


20

รับที่zshสามารถอุดตันไฟล์ทั้งหมดที่ได้รับคำสั่ง:

>*

ฉันคิดว่าการตั้งค่าตัวเลือกnoclobberจะเป็นความคิดที่ดี

ฉันสามารถใช้งานได้ตลอดเวลา>| fileหากฉันต้องการใช้พฤติกรรมการปิดบังเริ่มต้นทั้งใน bash และ zsh (zsh ยังอนุญาตให้ใช้ไวยากรณ์ทางเลือก>!file)

ฉันคาดว่าnoclobberจะไม่ได้รับการตั้งค่าเริ่มต้นเนื่องจากความเข้ากันได้ POSIX แต่เพื่อให้แน่ใจว่า:

มีข้อเสียในการตั้งค่าnoclobberหรือไม่?

อย่างไรก็ตามมีการตั้งค่าnoclobberสำหรับเชลล์แบบโต้ตอบเท่านั้นหรือไม่


3
ฉันประหลาดใจอย่างน้อย zsh ไม่ได้เตือนอย่างนั้นเนื่องจากมันเตือนบางสิ่งเช่นrm *...
ilkkachu

คำตอบ:


24

เหตุผลที่noclobberไม่ได้ตั้งไว้โดยค่าเริ่มต้นเป็นประเพณี เป็นเรื่องของการออกแบบส่วนต่อประสานกับผู้ใช้มันเป็นความคิดที่ดีที่จะทำให้ "สร้างไฟล์ใหม่นี้" เป็นการกระทำที่ง่ายและทำให้การกระทำที่อันตรายเป็นพิเศษยิ่งขึ้น "สร้างไฟล์ใหม่หรือเขียนทับไฟล์ที่มีอยู่" ดังนั้นจึงnoclobberเป็นความคิดที่ดี ( >ในการสร้างไฟล์ใหม่>|เพื่อเขียนทับไฟล์ที่มีอยู่) และน่าจะเป็นค่าเริ่มต้นหากเชลล์ได้รับการออกแบบในอีกไม่กี่ทศวรรษต่อมา

ฉันขอแนะนำให้ใช้สิ่งต่อไปนี้ในไฟล์เริ่มต้นเชลล์แบบโต้ตอบ ( .bashrcหรือ.zshrc):

set -o noclobber
alias cp='cp -i'
alias mv='mv -i'

ในแต่ละกรณี (การเปลี่ยนเส้นทางการคัดลอกการย้าย) เป้าหมายคือการเพิ่มอุปสรรค์พิเศษเมื่อการดำเนินการอาจมีผลข้างเคียงของการลบข้อมูลที่มีอยู่บางอย่างแม้ว่าการลบข้อมูลที่มีอยู่ไม่ใช่เป้าหมายหลักของการดำเนินการ ผมไม่ได้ใส่ในรายการนี้เนื่องจากการลบข้อมูลเป็นเป้าหมายหลักของrm -irm

ทราบว่าจะทำnoclobberและ-iมีตาข่ายความปลอดภัย หากพวกเขาเรียก, คุณได้ทำอะไรผิด ดังนั้นอย่าใช้มันเป็นข้ออ้างที่จะไม่ตรวจสอบสิ่งที่คุณเขียนทับ! ประเด็นก็คือคุณควรตรวจสอบว่าไฟล์เอาต์พุตไม่มีอยู่ หากคุณได้รับการบอกกล่าวfile exists: fooหรือoverwrite 'foo'?หมายความว่าคุณทำผิดพลาดและคุณควรรู้สึกไม่ดีและระมัดระวังมากขึ้น โดยเฉพาะอย่างยิ่งอย่าเข้าสู่นิสัยว่าyถ้าได้รับพร้อมท์ให้เขียนทับ (arguably, นามแฝงควรalias cp='yes n | cp -i' mv='yes n | mv -i'แต่กดCtrl+ Cทำให้ผลลัพธ์ดูดีกว่า): ถ้าคุณหมายถึงการเขียนทับ, ยกเลิกคำสั่ง, ย้ายหรือลบเอาท์พุท ไฟล์และเรียกใช้คำสั่งอีกครั้ง

สิ่งสำคัญคือไม่ให้มีนิสัยในการกระตุ้นความปลอดภัยเหล่านั้นเพราะถ้าคุณทำวันหนึ่งคุณจะอยู่ในเครื่องที่ไม่มีการกำหนดค่าของคุณและคุณจะสูญเสียข้อมูลเพราะการปกป้องที่คุณคาดหวังไว้ ทีนั่น

noclobberจะถูกตั้งค่าสำหรับเชลล์แบบโต้ตอบเท่านั้นเนื่องจาก.bashrcหรือ.zshrcถูกอ่านโดยเชลล์แบบโต้ตอบเท่านั้น แน่นอนคุณไม่ควรเปลี่ยนตัวเลือกเชลล์ในวิธีที่จะส่งผลต่อสคริปต์เนื่องจากอาจทำให้สคริปต์เหล่านั้นแตก


6
rmมีตัวเลือก-Iที่ฉันใช้และแนะนำ: "พร้อมท์หนึ่งครั้งก่อนที่จะลบไฟล์มากกว่าสามไฟล์หรือเมื่อลบแบบซ้ำ ๆ โดยมีการก้าวก่ายน้อยกว่า-iในขณะที่ยังให้การป้องกันข้อผิดพลาดส่วนใหญ่"
Reid

9
ฉันไม่แนะนำให้ใช้นามแฝง cp และ mv อีกครั้ง อย่างไรก็ตามการใช้-iเป็นอาร์กิวเมนต์เริ่มต้นสำหรับพวกเขาเป็นความคิดที่ดี แต่ควรใช้กับชื่อนามแฝงที่แตกต่างกันไม่ใช่ต้นฉบับ (เช่นฉันมักจะใส่alias copy="cp -i"และalias move="mv -i"ใน. bashrc ของฉัน) ทำไม? เนื่องจากโหมดความล้มเหลว จะเกิดอะไรขึ้นเมื่อคุณใช้เครื่องหรือผู้ใช้อื่นที่ไม่มีนามแฝง cp / mv ไฟล์อาจถูกเขียนทับโดยไม่ตั้งใจ (อาจตรวจไม่พบ!) โหมดความล้มเหลวที่สอดคล้องกับสำเนา / ย้ายนามแฝง: เชลล์บ่นว่าไม่รู้จักคำสั่ง
hlovdal

1
นอกจากนี้ยังมีโหมดความล้มเหลวเพิ่มเติมสำหรับ cp / mv alias: เมื่อเขียนเชลล์สคริปต์บางคนที่ใช้ใน cp = "cp -i" alias สามารถเขียนคำสั่ง cp ได้อย่างไม่ถูกต้องโดยคาดหวังว่ามันจะทำงานเหมือนในโหมดโต้ตอบเนื่องจากไม่มี ความแตกต่างของชื่อ ในทางตรงกันข้ามทุกครั้งที่ฉันเขียน "copy somefile / some / ที่ไหน" ฉันรู้ว่าฉันใช้นามแฝงไม่ใช่คำสั่ง cp โดยตรง และแม้ว่าฉันควรใส่สำเนาลงในไฟล์เชลล์มันก็จะล้มเหลวเช่นเดียวกับเชลล์ที่มีนามแฝงที่หายไป
hlovdal

1
ดังนั้น TL; DR คำแนะนำในการเริ่มต้นให้ใช้-iอาร์กิวเมนต์สำหรับ cp และ mv นั้นยอดเยี่ยม แต่คำแนะนำในการนำชื่อ cp และ mv กลับมาใช้ใหม่นั้นแย่มากอย่างน่ากลัว มันแย่มากที่ฉันต้องตอบคำถามลงคะแนน โปรดเปลี่ยนเพื่อใช้ชื่อนามแฝงอื่นและฉันจะให้คะแนนแทน
hlovdal

1
@TomHale คุณสามารถใช้alias RM='command rm'ซึ่งจะบอก zsh ให้ใช้คำสั่งภายนอกrmแทนนามแฝง วิธีการที่คุณจะได้ไม่ต้องพึ่งพาแทนก่อนหน้านี้--interactive=never -i
Adaephon

6

การตั้งค่าnoclobberตัวเลือกเชลล์ใน~/.bashrc(สำหรับbash) หรือ~/.zshrc(หรือแม่นยำยิ่งขึ้น$ZDOTDIR/.zshrcสำหรับzsh) จะทำให้แอปพลิเคชันทำงานในเซสชันเชลล์แบบโต้ตอบ

เชลล์แบบไม่โต้ตอบ (สคริปต์) ไม่อ่านไฟล์เหล่านี้

โดยปกติแล้วตัวเลือกของเชลล์จะไม่สืบทอดมาจากเปลือกหอยหลัก

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

ข้อเสียเพียงอย่างเดียวของการทำสิ่งนี้ที่ฉันเห็นคือคุณจะลืมซ้ำ ๆ ว่าคุณได้ตั้งค่าตัวเลือกอย่างน้อยในตอนแรก ต่อมาเช่นเดียวกับทุกชนิดของสิ่งเหล่านี้คุณจะเริ่มต้นที่จะใช้เป็นประจำ>|แม้ในกรณีที่คุณจริงอาจไม่ต้องการที่จะบังคับแฟ้ม (เช่นเดียวกับคนที่มีนามแฝงสำหรับrm, cpและmvกับ-iตัวเลือกการตั้งค่าเสมอในที่สุดก็เริ่มที่จะใช้งานเสมอ-fบนบรรทัดคำสั่ง)


2
ด้วยbashตัวเลือกจะสืบทอดมาหาก$SHELLOPTS( $BASHOPTSสำหรับตัวเลือกshopt) อยู่ในสภาพแวดล้อม (ไม่ใช่สิ่งที่คุณต้องการทำโดยทั่วไปด้วยเหตุผลเช่นนี้)
Stéphane Chazelas

3

ข้อเสียคือถ้าคุณคุ้นเคยกับการnoclobberใช้งานวันหนึ่งคุณจะใช้ระบบที่มันไม่ทำงานและคุณจะดำเนินการคำสั่งที่อาจเป็นอันตรายคาดว่าnoclobberจะช่วยให้คุณประหยัด ... และมันจะไม่ จากนั้นคุณจะต้องหวังว่าจะมีการสำรองข้อมูลที่เพียงพอล่าสุดเพื่อกู้คืนข้อมูลที่คุณทำลายเพราะคุณคิดว่าคุณจะถูกขอให้ยืนยันก่อน


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