递归mkdir

递归mkdir

是否有一个我忽略的 Linux 命令可以执行以下操作:(伪)

$ mkdir -R foo/bar/zoo/andsoforth

或者除了一次创建一个目录之外别无选择?

答案1

$ mkdir -p foo/bar/zoo/andsoforth

参数p代表“父母”。

答案2

使用mkdir -p对于大多数现代操作系统来说,这是一种简单的方法:

mkdir -p foo/bar/zoo/andsoforth

然而,mkdir -p许多手册中并不推荐。阅读 GNU 的文档make以及autoconf有关使用问题的信息mkdir -p

跨平台安装配置系统有自己的安全的替代品mkdir -p

CMake 在 shell 命令行中使用:

 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

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基于的跨平台版本dirname已添加到代码中。它的工作方式类似于dirname(正确使用路径/,仅具有基本名称的路径,具有尾随的路径/,具有和不具有尾随\ns的路径)。如果路径包含换行符或当前语言环境的某些无效字符,则此函数无法正常工作。它还将/( //, ///) 的任意组合替换为单个/

将行更改mkdir "$1" || return 1为,test -d "$1" || { mkdir "$1" || return 1; }因为mkdir如果路径存在,则错误终止,并且包含类似结构的路径需要进行此检查aaa\.(如果aaa不存在,则先前版本创建aaa,然后尝试再次创建它)。

如果路径已经存在,此版本的 mkd 不会生成错误(但在并行执行中仍然有可能生成此类错误)并且无法在命令行中获取多个目录。

答案3

-p命令中的选项mkdir使p没有目录根据需要(如果存在则不会出现错误):

mkdir -p foo/bar/zoo/andsoforth

另一种方法是,例如使用&&(如果指定的文件夹存在则出错):

mkdir foo && mkdir foo/bar && mkdir foo/bar/zoo && mkdir foo/bar/zoo/andsoforth

链接运算&&符用于将命令链接在一起,这样当且仅当前一个命令无错误退出时才运行下一个命令。

当然,第一种方式更好。

答案4

mkdir foo foo/bar foo/bar/zoo/ foo/bar/zoo/andsofort.

这应该可以做到。

相关内容