厨师(Chef)bash资源,command属性不起作用。

4

我有一个简单的食谱,看起来像这样:

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

它没有生效。它显示正在执行,但是它没有创建文件夹。如果我将 bash 更改为 execute,那么它就会工作。如果我将 command 更改为 code,那么它也会工作。但是在 bashexecute 文档中,command 的规格完全相同。是我做错了什么还是文档有误?
2个回答

3
引用Bash资源的属性文档:

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

因此,命令属性只是命令的名称,而不是要运行的完整代码。对于bash资源(以及所有其他脚本资源),应使用code属性发送要执行的代码。
因此,正确的资源定义如下:
bash "create folder" do
  code "mkdir -p /home/user/folder"
  not_if {::File.directory?("/home/user/folder")}
end

事实上,command属性的内容在那里并没有被使用到,它只是因为脚本资源继承自execute资源,从而继承了所有可能的属性。

最后要提醒的是,在创建目录时,应该使用内置于Chef的实际惯用directory资源,而不是像这样使用bash脚本:

directory "/home/user/folder" do
  recursive true
end

1
在使用Chef时,您应该使用Chef习语。这将使您和其他人的生活更加轻松,因为在Chef中事物是一致的。如果您想编写bash脚本,则可以这样做而不使用Chef。但是,如果您想使用Chef,则应遵循惯例。内置资源具有幂等性(即可重复性)。在目录资源的情况下,您还可以设置所有者和权限,并在需要时使用通知。 - Holger Just
1
关于可读性和约定:如果我看到一个“directory”资源,我立刻知道它创建了一个目录。如果我看到你的bash资源,我总是不得不手动阅读代码(和保护)才能理解它在做什么。一旦你开始做比创建目录更复杂的事情,你的bash片段就会失控。 - Holger Just
如果你只是想编写bash脚本,那么你应该使用fss。如果你关心脚本的幂等性和收敛性,那么你应该使用Chef或Puppet。 - sethvargo
嗯,如果你看到一个名为“创建文件夹”的资源或者看到mkdir命令,你应该立刻知道它的作用。当传输文件和启动服务更容易时,我使用chef资源,而不是编写相应的bash脚本,但已经是幂等的一行代码(-p选项确保了这一点,我实际上不需要保护)比阅读破碎的文档更快。我理解你的观点,但bash可以很好地处理文件系统交互,并且我可以轻松地使用保护来确保幂等性,就像它们的本意一样。 - Zook
execute 资源是否在幕后将其 command 翻译成代码?脚本资源继承属性但不继承功能,这很奇怪。 - Zook
基本上,脚本提供程序会将“代码”写入临时文件,然后使用“执行”提供程序运行所选解释器来运行该脚本。这就是为什么您无法覆盖命令的原因:生成的脚本就是命令。 - Holger Just

1
默认情况下,bash的行为是“用来运行脚本”。 默认情况下,执行的行为是“用来运行命令”。 您正在运行一个命令,而不是脚本,因此使用代码块或使用execute是有意义的。这两者之间的区别在文档中没有明确定义。我在文档中发现了至少3或4个完全错误的例子,并提交了更正,其中一些还未被采纳。

好的,我现在看到了它们之间的区别,但是它们都说:“name是资源块的名称;当command属性未作为配方的一部分指定时,name也是要执行的命令的名称”。并且它们在:run下面的:nothing的文本也是相同的。这真让人沮丧。 - Zook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接