仅当目录不存在时才如何mkdir?


1986

我正在编写一个Shell脚本以在AIX上的KornShell(ksh)下运行。我想使用mkdir命令创建目录。但是该目录可能已经存在,在这种情况下,我不想执行任何操作。因此,我想测试一下目录是否存在,或者抑制mkdir尝试创建现有目录时抛出的“文件存在”错误。

关于如何最好地做到这一点的任何想法?

Answers:


3292

尝试mkdir -p

mkdir -p foo

请注意,这还将创建任何不存在的中间目录。例如,

mkdir -p foo/bar/baz

将创建目录foofoo/bar以及foo/bar/baz如果它们不存在。

诸如GNU之类的某些实现作为更易读的别名mkdir包括在内mkdir --parents,但是POSIX / Single Unix Specification中未指定此别名,并且在macOS,各种BSD和各种商业Unix等许多常见平台上也不可用,因此应避免使用它。

如果在父目录不存在时想要一个错误,并且在目录不存在时想要创建该目录,则可以test首先确定目录的存在:

[ -d foo ] || mkdir foo

11
您使用的简短示例正是您不应该使用的示例。它正在逆转逻辑以节省编码空间,但应使用!和&&,对于那些阅读它的人来说更有意义。
Mike Q

16
@AndreasLarsen这个问题是关于mkdir类Unix系统的,而不是关于Windows的。-p符合POSIX / Single Unix规范是必需的,因此符合这些规范的任何意图都将支持-p。Windows完全不同,除非您使用Cygwin或MSYS之类的POSIX仿真层。
布莱恩·坎贝尔

22
我今天发现了一些有趣的东西mkdir -p,可以使用方括号!{}在命令中创建“复杂”目录树。看到这里:technosophos.com/2010/04/15/…–
herve

12
我宁愿使用@MikeQ ||代替,&&因为这样整行都具有正确的退出状态。重要的是,如果您的Shell与之一起运行,errexit或者该行是函数的最后一行,请切换大小写(无论如何)。
rudimeier

9
@herve与无关mkdir; shell将这样的表达式扩展为传递给的离散参数列表mkdir
chepner

176

这应该工作:

$ mkdir -p dir

要么:

if [[ ! -e $dir ]]; then
    mkdir $dir
elif [[ ! -d $dir ]]; then
    echo "$dir already exists but is not a directory" 1>&2
fi

如果目录不存在,它将创建一个目录,但是如果您要创建的目录的名称已经被目录以外的其他名称使用,则会发出警告。


我认为korn中没有-d运算符,而是-e用于文件/目录,并仅检查是否存在。同样,它们都在成功时返回0,所以!是多余的。如我错了请纠正我。
alkar

1
在这两个方面都是错误的,AFAIK。测试成功则返回true,并且-d也存在(至少在MacOS X上如此)
Alnitak 2009年

5
可能值得一提的是,这并不是十分线程安全的。在您检查目录是否存在到尝试写入之间,事情可能会发生变化。
贾斯汀·L.


73

用一个命令定义复杂的目录树

mkdir -p project/{lib/ext,bin,src,doc/{html,info,pdf},demo/stat/a}

如果存在,则没有错误,请根据需要创建父目录
Fedir RYKHTIK

18
请记住,这不是其mkdir本身的功能,而是执行命令的外壳。这被称为大括号扩展-AFAIK,只有Bash,ksh,zsh和C Shell支持它。
Daniel Kamil Kozar

3
如果逗号之间有空格,您可能会得到意想不到的结果。谨防。
Atlas7年7

1
@ Atlas7声明,您将需要转义通常属于正则表达式的字符。(即代替使用,folder name您需要使用folder\ name
John Hamilton

1
这不是答案。这是一个单独的主题,更适合作为注释。
克里斯·佩奇

40

如果您不想显示任何错误消息:

[ -d newdir ] || mkdir newdir

如果要显示自己的错误消息:

[ -d newdir ] && echo "Directory Exists" || mkdir newdir

20

旧的尝试和真实

mkdir /tmp/qq >/dev/null 2>&1

不会在其他许多解决方案都具备的竞争条件下完成您想要的工作。

有时最简单(最丑陋)的解决方案是最好的。


5
如果“ tmp”不存在,这将失败。也不会给您任何确认。
Mike Q

15

mkdir foo即使目录存在也可以工作。要使其仅在名为“ foo”的目录不存在时起作用,请尝试使用该-p标志。

例子:-

mkdir -p foo

仅当目录不存在时,才会创建名为“ foo”的目录。:)


2
如@BrianCampbell所述,这还将在路径中创建任何其他目录。如果例如某个卷被卸载,则可能会很危险,因为它可能会在安装点中创建目录。
uliwitness

11
directory_name = "foo"

if [ -d $directory_name ]
then
    echo "Directory already exists"
else
    mkdir $directory_name
fi

10

或者,如果您想先检查是否存在:

if [[ ! -e /path/to/newdir ]]; then
            mkdir /path/to/newdir
fi

-e是对korn shell的存在测试。

您也可以尝试使用Google搜寻的Korn Shell手册。


10

在Windows 8+系统上,mkdir不再支持-p开关。

您可以使用此:

IF NOT EXIST dir_name MKDIR dir_name

10
OP与AIX内核有关……与Windows无关,不是吗?
J. Chomel

9

请参考手册页man mkdir以了解选项-p

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

这将在给定路径中创建所有目录,如果存在则不会引发错误,否则它将在给定路径中从左到右创建所有目录。请尝试以下命令。目录newdiranotherdir并且在发出此命令之前不存在

正确用法

mkdir -p /tmp/newdir/anotherdir

执行命令后,您可以在/ tmp下查看newdiranotherdir创建。您可以多次发出此命令,该命令始终具有exit(0)。由于这个原因,大多数人在使用这些实际路径之前在外壳程序脚本中使用此命令。


8

您可以使用if循环来检查目录是否存在,如果没有退出,则可以创建目录。

1)dir = / home / dir_name

if [ ! -d $dir ]
then
     mkdir $dir
else
     echo "Directory exists"  
fi

2)您可以使用带有-p选项的mkdir来创建目录。它将检查目录是否不可用。

mkdir -p $dir

mkdir -p还允许创建目录的树结构。如果要使用相同的命令创建父目录和子目录,可以选择mkdir -p

mkdir -p /home/parent_dir /home/parent_dir/child1 /home/parent_dir/child2

使用if循环有任何优势吗?为什么有人会选择超过-p选项?
pedram bashiri

1
我已经分享了不存在文件夹时创建文件夹的方法。这取决于对一个的要求。如果您有一个用例,需要检查文件夹是否不存在并且想要跟踪该文件夹,那么可以使用解决方案1。如果没有关系,可以使用解决方案2,它将创建该文件夹。如果不存在。
AbhinavVaidya18年

我没有看到循环。
阿米特·奈杜

3

这是一个简单的函数(bash shell),可让您创建一个不存在的目录。

#----------------------------------
# Create a directory if it doesn't exist
#------------------------------------
createDirectory() {
    if [ ! -d $1 ]
        then
        mkdir -p $1
    fi
}

您可以将上述函数调用为:

createDirectory / tmp / fooDir / BarDir

如果它们不存在,上面的代码将创建fooDir和BarDir。请注意mkdir命令中的“ -p”选项,该选项以递归方式创建目录。希望这可以帮助。



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.