เหตุใด mkdir จึงไม่มีแฟล็ก -p ที่ตั้งค่าไว้ตามค่าเริ่มต้นเพื่ออนุญาตการสร้างไดเรกทอรีที่ซ้อนกัน


11

ฉันไม่เห็นเหตุผลว่าทำไมการ-pตั้งค่าสถานะmkdirไม่ควรตั้งค่าเริ่มต้น

  -p, --parents     no error if existing, make parent directories as needed

มันเป็นคำสั่งที่ไม่ทำลายล้างจากสิ่งที่ฉันเห็น ฉันพลาดบางสิ่งบางอย่างที่สำคัญเกี่ยวกับวิธีการทำงานนี้หรือไม่?

ประการที่สองมีวิธีที่ง่ายที่จะทำให้สิ่งนี้เป็นพฤติกรรมเริ่มต้นmkdirใช่หรือไม่


2
ใส่นี้ใน .bashrc alias mkdir="mkdir -p"ของคุณ:
Kevin

หลังจากการอภิปรายทั้งหมดฉันตัดสินใจที่จะไปกับนามแฝงของmkdp
Treffynnon

คำตอบ:


6

นี่เป็นคุณสมบัติเสริมที่ไม่ต้องการเสมอ - โดยเฉพาะในสคริปต์ พิจารณาข้อเสียดังต่อไปนี้ในกรณีของสคริปต์:

  • ความจริงที่ว่าไดเรกทอรีนั้นไม่มีอยู่แล้ว: หากสคริปต์ควรใส่บางไฟล์ในไดเรกทอรีที่สร้างขึ้นใหม่และไดเรกทอรีนั้นมีอยู่แล้วและมีไฟล์อยู่สคริปต์อาจทำให้เกิดความยุ่งเหยิงมากมาย (มันจะลำบากมากที่จะกรองไฟล์ที่วางไว้ในสคริปต์ภายหลัง)
  • ที่ด้านพลิกของด้านบนสคริปต์บางตัว (หรือบางส่วนของ) อาจขึ้นอยู่กับโครงสร้างไดเรกทอรีที่สร้างไว้ก่อนหน้านี้ ยกตัวอย่างเช่นสคริปต์การติดตั้งแพคเกจอาจจะต้องใส่ห้องสมุดใน subdir /usr/local/lib/GreatSoftware/ImportantPartOfItแต่ห้องสมุดขึ้นอยู่กับการเชื่อมโยง / /usr/local/lib/GreatSoftwareเพื่อสิ่งที่อยู่ภายใต้ หากสิ่งนี้ขาดหายไปสคริปต์ไม่ควรดำเนินการต่อ

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


คุณสามารถสร้างนามแฝงได้หากคุณต้องการใช้mkdir -pในเชลล์เสมอ:

alias mkdir='mkdir -p'

(สิ่งนี้ควรไปที่การตั้งค่า.bashrcเชลล์ของคุณหรืออะไรก็ตามที่คุณใช้)


1
ฉันจะไม่แนะนำให้นามแฝงคำสั่งมาตรฐานเพื่อให้มันทำงานในลักษณะที่ไม่ได้มาตรฐาน ซึ่งจะทำให้สคริปต์ไม่สามารถพกพาได้และอาจทำให้ผู้อ่านสับสน การสร้างนามแฝงใหม่หรือฟังก์ชั่นเช่นalias mkdp="mkdir -p"จะแนะนำให้เลือกมากขึ้น
jlliagre

2
@jlliagre ไม่มันจะไม่ส่งผลต่อสคริปต์ นามแฝงที่กำหนดไว้ในเครื่อง.bashrcจะไม่ส่งผลกระทบต่อสภาพแวดล้อมของพวกเขา
rozcietrzewiacz

แน่นอน แต่คุณพลาดจุดของฉัน การใช้นามแฝงคำสั่งมาตรฐานเพื่อเปลี่ยนพฤติกรรมของมันแม้จะเป็นการใช้งานของคุณเองก็ไม่ใช่วิธีปฏิบัติที่แนะนำ alias rm='rm -i'ตัวอย่างที่เลวร้ายที่สุดเป็นที่แพร่หลาย
jlliagre

1
@jlliagre ไม่แนะนำโดยใคร? ;) แต่ใช่ฉันเห็นด้วยตัวเองฉันจะใช้นามแฝงที่แตกต่างกัน - แต่สำหรับเหตุผลเชิงปฏิบัติไม่ใช่อุดมการณ์ ฉันยังไม่คิดว่าrm -iนามแฝงจะไม่ดีอยู่เสมอ - แม้ว่าอาจนำไปสู่นิสัยที่ไม่ดี แน่นอนว่านามแฝงคำสั่งทั้งหมดจะไม่ดีเท่ากัน / ไม่ดี - พิจารณาls="ls --color=auto"หรือssh="TERM=xterm ssh"เป็นตัวอย่าง
rozcietrzewiacz

คำแนะนำของฉันไม่มีอุดมการณ์ นามแฝง rm มีความรับผิดชอบทางอ้อมต่อไฟล์ที่สูญหายจำนวนมาก (ฉันได้พบผู้ที่ตกเป็นเหยื่อของนามแฝงนี้แล้ว) ฉันสงสัยว่า mkdir จะมีผลข้างเคียงที่ไม่พึงประสงค์น้อยมาก แน่นอนว่าฉันไม่ได้ขัดกับเครื่องสำอางไม่ใช่เป็นพฤติกรรมการเปลี่ยนแปลงเช่นตัวอย่าง ssh และ ls ของคุณ
jlliagre

16

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

แต่สาเหตุที่มันเป็นอย่างอื่นคือประวัติศาสตร์ รุ่นพื้นฐานของmkdirไม่ได้สร้างไดเรกทอรีหลัก นี่คือสาเหตุที่การแจกแจง X11 มาพร้อมกับคำสั่งชื่อmkdirhierซึ่งสามารถทำงานนี้ได้สำเร็จ: ตรวจสอบว่ามีไดเรกทอรีหลักอยู่และสร้างถ้าจำเป็น

ต่อมาในฟังก์ชั่นนี้ถูกเพิ่มเข้าไปในคำสั่งmkdirใน UNIX หลายเวอร์ชัน (ฉันไม่รู้ว่ามันอยู่ในมาตรฐาน POSIX ทุกวันนี้) -pเพื่อรักษาความเข้ากันได้คุณลักษณะนี้ถูกสร้างขึ้นโดยการเปิดธงตัวเลือก:

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

ตัวอย่าง:

 if mkdir /backup/$(uname -n)/$(date +%Y%m%d)
  then
    perform_backup ...

ในตัวอย่างนี้ไดเร็กทอรีจะถูกสร้างและการสำรองข้อมูลจะดำเนินการแม้เป็นระบบไฟล์/backupไม่ถูกเมาต์และพาเรนต์/backup/$(uname -n)ไม่มีอยู่หากค่าดีฟอลต์จะเป็นวิธีอื่น

Rule of thumb: เป็นการดีที่จะไม่เปลี่ยนพฤติกรรมเริ่มต้นของเครื่องมือใด ๆ หากต้องการให้ตัวเลือกในการอนุญาตให้เปลี่ยนพฤติกรรมเริ่มต้น


2
ฉันชอบตัวอย่างภูเขาที่คุณใช้ที่นี่ ฉันไม่ได้นึกถึงสถานการณ์นั้น
Treffynnon

1
ตัวเลือก -p (และ -m) ถูกนำมาใช้โดย System V ในปี 1983 ทั้งคู่เป็นส่วนหนึ่งของมาตรฐาน POSIX
jlliagre

4

ฉันคิดว่านี่เป็นปรัชญาที่ดี คำสั่งเปล่าmkdir (1) (ไม่มีตัวเลือก) แสดงถึงการเรียกระบบmkdir (2)ซึ่งให้การทำงานในเชลล์โดยไม่ต้องทำอะไรมากหรือน้อย


4

ในการเริ่มต้นมีเพียงmkdirคำสั่งเปลือย ตามหลักการออกแบบของ Unix คำสั่งง่าย ๆ นี้ใช้งานง่าย ๆ อย่างหนึ่ง: การสร้างไดเรกทอรี

ต่อมาmkdirได้รับ-pตัวเลือกในการจัดการกรณีการใช้งานทั่วไปที่ผู้เรียกต้องการสร้างศูนย์หนึ่งหรือหลายไดเรกทอรีเพื่อให้แน่ใจว่าเส้นทางที่เฉพาะเจาะจงอยู่ นี่ไม่ใช่การดำเนินการเริ่มต้นด้วยเหตุผลหลายประการ ครั้งแรกที่ระบบไม่ได้ทั้งหมดมีคุณสมบัติที่ซับซ้อนมากขึ้นนี้และต้องมี-pตัวเลือกหมายความว่าสคริปต์ที่ใช้มันจะได้รับข้อความแสดงข้อผิดพลาดที่เหมาะสม (สิ่งที่ต้องการmkdir: invalid option -z) มากกว่าแปลกล้มเหลวในการสร้างไดเรกทอรีเป็นครั้งคราว ประการที่สองและที่สำคัญที่สุดพฤติกรรมของmkdir -pไม่สามารถใช้ทดแทนได้mkdirในทุกกรณี

โดยเฉพาะอย่างยิ่งใน fileystems มากที่สุดmkdirคือการดำเนินงานของอะตอม หากโปรแกรมรันmkdir playgroundและคำสั่งสำเร็จโปรแกรมจะรู้ว่าสร้างplaygroundไดเร็กทอรี สิ่งนี้อนุญาตให้โปรแกรมรักษาไดเรกทอรีใหม่เป็นสนามเด็กเล่นเอกสิทธิ์ของมัน: หากอินสแตนซ์อื่นของโปรแกรมเดียวกันทำงานพร้อมกันการเรียกใช้mkdir playgroundจะล้มเหลว เห็นได้ชัดว่าคุณสมบัตินี้ไม่ได้จัดไว้ให้mkdir -pเนื่องจากจะอนุญาตให้อาร์กิวเมนต์มีอยู่

หากmkdir -pมีอยู่ตั้งแต่เริ่มต้นอาจเป็นโหมดเริ่มต้นพร้อมmkdir -aคำสั่งสำหรับการสร้างไดเรกทอรีเดียว แต่นั่นก็ไม่ได้เป็นไปตามปรัชญาการออกแบบของ Unix: ยูทิลิตี้พื้นฐานส่วนใหญ่เป็นตัวห่อหุ้มรอบ ๆ พื้นฐานซึ่งมีพฤติกรรมที่น่าสนใจมากกว่า


2

สำหรับฉันปัญหาคือว่าพฤติกรรมของตัวเลือก -p ถ้ามันเป็นค่าเริ่มต้นเป็นหลักผลข้างเคียง มันเพิ่มความซับซ้อนให้กับคำสั่งโดยทำสิ่งเพิ่มเติมจากสิ่งที่คุณขอให้ทำ มันเป็นสิ่งที่มองไม่เห็นอีกอย่างที่ต้องจำ หนึ่งในกฎพื้นฐานของการฝึกการเขียนโปรแกรมเสียงคือการหลีกเลี่ยงผลข้างเคียง

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

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