การใช้mkdir -p
เป็นวิธีที่ง่ายสำหรับระบบปฏิบัติการที่ทันสมัยที่สุด:
mkdir -p foo/bar/zoo/andsoforth
อย่างไรก็ตามmkdir -p
ไม่แนะนำในคู่มือจำนวนมาก อ่านเอกสารเกี่ยวกับGNU make
และautoconf
ปัญหาเกี่ยวกับการใช้mkdir -p
:
การติดตั้งข้ามแพลตฟอร์มและระบบกำหนดค่ามีทางเลือกที่mkdir -p
ปลอดภัยสำหรับตนเอง
CMake เพื่อใช้ในเชลล์คำสั่ง:
cmake -E make_directory foo/bar/zoo/andsoforth
Autoconf ที่จะใช้ในสคริปต์ด้วยการประมวลผลล่วงหน้า:
AS_MKDIR_P(foo/bar/zoo/andsoforth)
หรือ:
AC_PROG_MKDIR_P(foo/bar/zoo/andsoforth)
แต่โซลูชั่นเหล่านี้ต้องใช้cmake
หรือautoconf
( M4
) เครื่องมือในการติดตั้ง (และการประมวลผลล่วงหน้าที่เป็นไปได้)
คุณสามารถใช้install-sh
สคริปต์พร้อม-d
ตัวเลือก:
install-sh -d foo/bar/zoo/andsoforth
สคริปต์นี้ใช้autoconf
และautomake
โปรเจ็กต์ ฉันคิดว่ามันจะต้องเป็นทางออกที่ปลอดภัยที่สุด
ในขณะที่ฉันกำลังค้นหาโซลูชันข้ามแพลตฟอร์มสำหรับมาตรฐาน/bin/sh
โดยไม่ต้องพึ่งพา แต่ยังไม่พบ ดังนั้นฉันจึงเขียนสคริปต์ถัดไปที่อาจไม่เหมาะ แต่ฉันคิดว่ามันเป็นไปตามข้อกำหนดแพลตฟอร์มข้ามส่วนใหญ่ :
#! /bin/sh
cdirname() # cross platform alternative for 'dirname'
{
# $1 - path
test $# -eq 1 || { echo "Procedure 'cdirname' must have only one parameter. Scripting error."; exit 1; }
echo "$1" | sed -n -e '1p' | sed -e 's#//*#/#g' -e 's#\(.\)/$#\1#' -e 's#^[^/]*$#.#' -e 's#\(.\)/[^/]*$#\1#' -
}
mkd() # cross platform alternative for 'mkdir -p'
{
# $1 - directory to create
test $# -eq 1 || { echo "Function 'mkd' can create only one directory (with it's parent directories)."; exit 1; }
test -d "$1" && return 0
test -d "$(cdirname "$1")" || { mkd "$(cdirname "$1")" || return 1; }
test -d "$1" || { mkdir "$1" || return 1; }
return 0
}
สคริปต์นี้สามารถนำมาใช้สำหรับระบบเก่าที่ตัวเลือก-p
สำหรับการmkdir
ขาด
sed
-based แพลตฟอร์มข้ามเวอร์ชันของdirname
ถูกเพิ่มไปยังรหัส มันทำงานด้วยวิธีที่คล้ายกับdirname
(แก้ไขด้วยพา ธ/
, พา ธที่มีชื่อฐานเท่านั้น, พา ธ ที่มีการต่อท้าย/
, พา ธ ที่มีและไม่มีการต่อท้าย\n
) ฟังก์ชันนี้ไม่สามารถทำงานได้อย่างถูกต้องหากเส้นทางมีการขึ้นบรรทัดใหม่หรืออักขระที่ไม่ถูกต้องสำหรับสถานที่ปัจจุบัน นอกจากนี้ยังแทนที่การรวมกันของ/
( //
, ///
) ด้วยซิงเกิล/
เปลี่ยนบรรทัดmkdir "$1" || return 1
เป็นtest -d "$1" || { mkdir "$1" || return 1; }
เพราะmkdir
ยุติด้วยข้อผิดพลาดหากมีเส้นทางอยู่และต้องใช้การตรวจสอบนี้สำหรับเส้นทางที่มีสิ่งปลูกสร้างเช่นaaa\.
(หากaaa
ไม่มีอยู่เวอร์ชันก่อนหน้าจะสร้างขึ้นaaa
จากนั้นลองสร้างอีกครั้ง)
mkd รุ่นนี้ไม่ได้สร้างข้อผิดพลาดหากเส้นทางมีอยู่แล้ว (แต่ก็ยังมีความเป็นไปได้ที่จะสร้างข้อผิดพลาดในการประมวลผลแบบขนาน) และไม่สามารถรับหลายไดเรกทอรีในบรรทัดคำสั่ง