Chef bash资源,命令属性不为';行不通

Chef bash资源,命令属性不为';行不通,bash,chef-infra,Bash,Chef Infra,我有一个简单的食谱如下: bash "create folder" do command "mkdir -p /home/user/folder" not_if {::File.directory?("/home/user/folder")} end directory "/home/user/folder" do recursive true end 它不起作用。它说它正在执行,但它没有创建文件夹。如果我将bash更改为execute,那么它就会工作。如果我将命令更改为代码,则

我有一个简单的食谱如下:

bash "create folder" do
  command "mkdir -p /home/user/folder"
  not_if {::File.directory?("/home/user/folder")}
end
directory "/home/user/folder" do
  recursive true
end
它不起作用。它说它正在执行,但它没有创建文件夹。如果我将
bash
更改为
execute
,那么它就会工作。如果我将
命令
更改为
代码
,则它可以工作。但是和文档在
命令上的规格基本相同


我做错了什么还是文档做错了?

bash的默认行为是
用于运行脚本

execute的默认行为是
用于运行命令


您运行的是一个命令,而不是脚本,因此您应该使用代码块或使用execute。两者的区别是。。。文档中没有很好的定义。我在文档中发现了至少3或4个完全错误的示例,并提交了更正,其中一些示例尚未进行更正。

引用文档的属性:

代码:要执行的带引号(“”)的代码字符串。
命令:要执行的命令的名称。默认值:资源块的名称(请参阅上面的语法部分)

因此,command属性只是命令的名称,而不是要运行的完整代码。对于bash资源(以及所有其他资源),您应该使用
code
属性来发送要执行的代码

因此,正确的资源定义是:

bash "create folder" do
  code "mkdir -p /home/user/folder"
  not_if {::File.directory?("/home/user/folder")}
end
事实上,
命令
属性的内容没有在任何地方使用,它只是在那里,因为脚本资源继承了
执行
资源,从而继承了其所有可能的属性

最后,要创建目录,您应该使用Chef内置的实际惯用
目录
资源,而不是像下面这样的bash脚本:

bash "create folder" do
  command "mkdir -p /home/user/folder"
  not_if {::File.directory?("/home/user/folder")}
end
directory "/home/user/folder" do
  recursive true
end

好的,我现在看到了这个区别,但它们都说“
name
是资源块的名称;当
command
属性未指定为配方的一部分时,
name
也是要执行的命令的名称”。它们在
:run
下有相同的
:nothing
文本。这很令人沮丧。在使用Chef时,你应该使用Chef成语。这将使你的生活和其他人的生活更加轻松,因为在厨师中事情是一致的。如果您想编写bash脚本,可以这样做,而不必使用Chef。但是如果你想使用厨师,你应该遵循惯例。内置资源具有内置的幂等性(即重复性)。对于目录资源,您还可以设置所有者和权限,并在需要时使用通知。关于可读性和约定:如果我看到
目录
资源,我立即知道它创建了一个目录。如果我看到您的bash资源,我总是需要手动阅读代码(和守卫)来理解它在做什么。一旦你开始做比创建目录更复杂的事情,你的bash代码片段就会失控。如果你关心脚本的幂等性和收敛性,你应该使用Chef或Puppet。呃,如果你看到一个名为“create folder”的资源,或者如果你看到一个
mkdir
命令,你也应该立即知道它的作用。当编写相应的bash脚本(例如用于传输文件和启动服务)比编写相应的bash脚本更容易时,我使用chef资源,但是已经是幂等的一行程序(选项
-p
确保我实际上不需要保护)比读取损坏的文档更快。我大体上理解您的观点,但是bash处理文件系统交互的能力很好,而且我可以很容易地确保与guards的幂等性,正如它们所希望的那样。
execute
资源是否在幕后将其
命令
转换为代码?奇怪的是,脚本资源继承的是属性,而不是它的功能。