Mkdir

遞歸 mkdir

  • August 5, 2020

是否有一個我忽略的 linux 命令可以執行以下操作:(偽)

$ mkdir -R foo/bar/zoo/andsoforth

或者除了一次創建一個目錄之外別無選擇?

$ mkdir -p foo/bar/zoo/andsoforth

參數p代表“父母”。

**對於大多數現代作業系統來說,使用mkdir -p**是一種簡單的方法:

mkdir -p foo/bar/zoo/andsoforth

但是,mkdir -p在許多手冊中並不推薦。閱讀 GNU 的文件make以及autoconf關於使用的問題mkdir -p

跨平台安裝和配置系統有自己的安全替代方案mkdir -p

在 shell 命令行中使用的 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)

但是這些解決方案需要cmakeautoconf( M4) 安裝工具(以及可能的預處理)

您還可以使用帶有選項install-sh的腳本:-d

install-sh -d foo/bar/zoo/andsoforth

該腳本由autoconfautomake項目使用。我認為這一定是最安全的解決方案。

當時我正在尋找一種/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
}

此腳本可用於沒有 for 選項的舊-p系統mkdir

sed-基於跨平台的版本dirname被添加到程式碼中。它的工作方式類似於dirname(正確使用 path /,僅帶有基本名稱的路徑,帶有尾隨/的路徑,帶有和不帶有尾隨\ns 的路徑)。如果路徑包含換行符或目前語言環境的某些無效字元,則此功能無法正常工作。/它還將( //, ) 的任何組合替換///為單個/

將行更改mkdir "$1" || return 1test -d "$1" || { mkdir "$1" || return 1; }因為mkdir如果路徑存在則以錯誤終止,並且對於包含結構的路徑需要此檢查aaa\.(如果aaa不存在以前的版本創建aaa然後嘗試再次創建它)。

如果 path 已經存在,這個版本的 mkd 不會產生錯誤(但它仍然有可能在並行執行中產生這樣的錯誤)並且無法在命令行中獲取多個目錄。

引用自:https://unix.stackexchange.com/questions/49263