是否有一个我忽略的 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
:
- http://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/html_node/Limitations-of-Usual-Tools.html#Limitations-of-Usual-Tools
- http://www.gnu.org/savannah-checkouts/gnu/make/manual/html_node/Utilities-in-Makefiles.html
跨平台安装配置系统有自己的安全的替代品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)
但这些解决方案需要安装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
基于的跨平台版本dirname
已添加到代码中。它的工作方式类似于dirname
(正确使用路径/
,仅具有基本名称的路径,具有尾随的路径/
,具有和不具有尾随\n
s的路径)。如果路径包含换行符或当前语言环境的某些无效字符,则此函数无法正常工作。它还将/
( //
, ///
) 的任意组合替换为单个/
将行更改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.
这应该可以做到。