为什么默认情况下mkdir没有设置-p标志以允许嵌套目录创建?


11

我看不出为什么默认情况下不应该设置-p标志mkdir

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

从我所见,这是一个非破坏性的命令。我是否错过了一些重要的工作方式?

其次,有没有一种简单的方法可以使它成为默认行为mkdir


2
把它放在你的.bashrc:中alias mkdir="mkdir -p"
凯文

经过所有讨论,我决定使用别名mkdp
Treffynnon

Answers:


6

这是一项可选功能,并非总是需要的-特别是在脚本中。考虑脚本的以下缺点:

  • 没有报告目录已经存在的事实:如果脚本应该将一些文件放置在新创建的目录中,并且该目录已经存在并包含文件,则该脚本会造成很多混乱。(稍后过滤掉脚本所放置的文件会很麻烦。)
  • 在上述情况的另一面,某些脚本(或其中的一部分)可能取决于先前创建的目录结构(可能由其他包/脚本)。例如,软件包安装脚本可能需要将库放在一个子目录中/usr/local/lib/GreatSoftware/ImportantPartOfIt,但是库依赖于/链接到的内容/usr/local/lib/GreatSoftware。如果缺少此脚本,则脚本不应继续。

通用行为mkdir使它变得轻松自然,因为据报道这种情况并可以立即发现。


如果要始终mkdir -p在外壳中使用,可以为其命名:

alias mkdir='mkdir -p'

(这应该转到您.bashrc或您的shell使用的任何配置。)


1
我不建议别名标准命令以使其具有非标准方式。这将使脚本不可移植,并可能使读者感到困惑。建议创建一个新的别名或函数alias mkdp="mkdir -p"
jlliagre 2011年

2
@jlliagre不,它不会影响脚本。在本地定义的别名.bashrc不会(通常)影响其环境。
rozcietrzewiacz,2011年

的确,但是您错过了我的观点。建议不要对标准命令使用别名来更改其行为,甚至供您自己使用。最糟糕的例子是无处不在alias rm='rm -i'
jlliagre 2011年

1
@jlliagre不推荐给谁?;)但是,是的,我同意,我本人宁愿使用其他别名-但出于实际而非意识形态的原因。我也不认为rm -i别名总是不好的-尽管可能会导致不良习惯。当然,并非所有命令别名都一样好/坏-考虑ls="ls --color=auto"ssh="TERM=xterm ssh"举例。
rozcietrzewiacz 2011年

我的建议没有什么思想上的。rm别名间接导致许多丢失的文件(我遇到了很多该别名的受害者)。我怀疑mkdir在较小程度上具有不需要的副作用。当然,我不反对外观变化,也不反对行为变化,例如您的ssh和ls示例。
jlliagre

16

当然,有人可能会争辩说父目录创建应该是默认目录,如果父目录不存在,可以使用某些检查选项来阻止目录创建。

但是,相反的原因仅仅是历史。mkdir的基本版本未创建父目录。这就是X11发行版附带一个名为mkdirhier的命令的原因,该命令能够完成此任务:检查父目录是否存在,并在必要时创建它们。

稍后,此功能已添加到许多UNIX版本的命令mkdir中(现在不知道它是否在POSIX标准中)。为了保持兼容性,可以通过打开选项标志来使此功能可用-p

为什么默认启用它不好?如果父目录不存在,脚本可能依赖于mkdir失败。特别是作为root用户时,默认情况下创建目录树可能很危险。

例:

 if mkdir /backup/$(uname -n)/$(date +%Y%m%d)
  then
    perform_backup ...

在此示例中,即使默认情况下是相反的方式,也将创建目录并执行备份,即使/backup未安装文件系统且父级/backup/$(uname -n)不存在。

经验法则:最好不要更改任何工具的默认行为。如果需要,请提供允许更改默认行为的选项。


2
我喜欢您在这里使用的安装示例。我没有想到那种特殊的情况。
Treffynnon 2011年

1
-p(和-m)选项由System V在1983年引入。这两个选项绝对是POSIX标准的一部分。
jlliagre 2011年

4

我认为这是一种哲学。裸露的mkdir(1)命令(不带选项)表示mkdir(2)系统调用,它在shell中提供其功能,或多或少不执行任何操作。


4

开始时,只有光秃秃的mkdir命令。根据Unix的设计原则,此简单命令执行一项简单任务:创建目录。

后来,mkdir获得了一个-p选项来处理一个常见的用例,在该用例中,调用者要创建零个,一个或多个目录以确保存在特定路径。由于多种原因,未将其设为默认操作。首先,并非所有系统都具有更复杂的功能,并且要求使用该-p选项意味着使用该功能的脚本会收到合理的错误消息(类似mkdir: invalid option -z),而不是偶尔无法创建目录。其次,也是最重要的mkdir -p是,的行为并非mkdir在所有情况下都是兼容的替代品。

特别是在大多数文件系统上,mkdir原子操作。如果程序运行mkdir playground并且命令成功执行,则程序将知道它已创建playground目录。这使程序可以将新目录视为其独占场所:如果同一程序的另一个实例正在同时运行,则其调用mkdir playground将失败。显然没有提供此属性,mkdir -p因为它允许参数存在。

如果mkdir -p从一开始就存在,则可以将其设置为默认模式,例如mkdir -a单目录创建命令。但这并不会遵循通常的Unix设计哲学:大多数基本实用程序都是围绕基本基元的简单包装,其行为奇特(如一次性创建多个目录)需要一些高级选项。


2

对我来说,问题在于-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.