

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 示例 7：运行命令和脚本
<a name="cookbooks-101-basics-commands"></a>

**重要**  
该 AWS OpsWorks Stacks 服务于 2024 年 5 月 26 日终止，新客户和现有客户均已禁用。我们强烈建议客户尽快将其工作负载迁移到其他解决方案。如果您对迁移有疑问，请通过 re [AWS : Post 或通过 Pre](https://repost.aws/) mium Su [AWS pp](https://aws.amazon.com/support) ort 与 AWS 支持 团队联系。

Chef 资源可以在实例上处理各种任务，但有时最好使用 shell 命令或脚本。例如，您可能已经拥有用于完成特定任务的脚本，继续使用它们而不是实施新的代码会更容易。本节介绍了如何在实例上运行命令或脚本。

**Topics**
+ [运行命令](#cookbooks-101-basics-commands-script)
+ [运行脚本](#cookbooks-101-basics-commands-execute)

## 运行命令
<a name="cookbooks-101-basics-commands-script"></a>

[https://docs.chef.io/chef/resources.html#script](https://docs.chef.io/chef/resources.html#script) 资源会运行一个或多个命令。它支持 csh、bash、Perl、Python 和 Ruby 命令解释器，因此可用于 Linux 或 Windows 系统，前提是它们已安装适当的解释器。本主题介绍了如何在 Linux 实例上运行简单的 bash 命令。Chef 还支持 [powershell\$1script](https://docs.chef.io/chef/resources.html#powershell-script) 和 [batch](https://docs.chef.io/chef/resources.html#batch) 资源在 Windows 上运行脚本。有关更多信息，请参阅 [运行 Windows PowerShell 脚本](cookbooks-101-opsworks-opsworks-powershell.md)。

**开始使用**

1. 在 `opsworks_cookbooks` 目录中，创建名为 `script` 的实例并导航到其中。

1. 将包含以下内容的 `metadata.rb` 文件添加到 `script`。

   ```
   name "script"
   version "0.1.0"
   ```

1. 如[示例 1：安装软件包](cookbooks-101-basics-packages.md)中所述，初始化和配置 Test Kitchen，并从 `platforms` 列表中删除 CentOS。

1. 在 `script` 中创建名为 `recipes` 的子目录。

您可以通过使用 `script` 资源本身来运行命令，但是 Chef 还支持一组特定于命令解释器的资源版本，这些资源版本根据解释器命名。以下配方使用 [https://docs.chef.io/chef/resources.html#bash](https://docs.chef.io/chef/resources.html#bash) 资源运行简单的 bash 脚本。

```
bash "install_something" do
  user "root"
  cwd "/tmp"
  code <<-EOH
    touch somefile
  EOH
  not_if do
    File.exists?("/tmp/somefile")
  end
end
```

`bash` 资源的配置如下所示。
+ 它使用默认操作 `run`，该操作会运行 `code` 块中的命令。

  此示例有一个命令 `touch somefile`，但是 `code` 块可能包含多个命令。
+ `user` 属性会指定执行相应命令的用户。
+ `cwd` 属性指定工作目录。

  在本示例中，`touch` 会在 `/tmp` 目录中创建一个文件。
+ 如果该文件已经存在，则 `not_if` guard 属性会指示资源不采取任何行动。

**运行配方**

1. 创建包含前面示例代码的 `default.rb` 文件，并将其保存至 `recipes`。

1. 运行 `kitchen converge`，然后登录到实例，以验证相应文件是否在 `/tmp` 中。

## 运行脚本
<a name="cookbooks-101-basics-commands-execute"></a>

`script` 资源很方便，尤其是当您只需要运行一两个命令时更是如此，但是通常最好将脚本存储在某个文件中，然后执行该文件。[https://docs.chef.io/chef/resources.html#execute](https://docs.chef.io/chef/resources.html#execute) 资源在 Linux 或 Windows 上运行指定可执行文件 (包括脚本文件)。本主题修改了来自前面示例的 `script` 说明书，以使用 `execute` 运行简单的 shell 脚本。您可将此示例轻松扩展为更复杂的脚本，或其他类型的可执行文件。

**设置脚本文件**

1. 将 `files` 子目录添加到 `script`，并将 `default` 子目录添加到 `files`。

1. 创建名为 `touchfile` 的包含以下内容的文件，然后将其添加到 `files/default` 中。此示例中使用了常见的 Bash 解释器行，但如果需要，可以替换为适用于您的 shell 环境的解释器。

   ```
   #!/usr/bin/env bash
   touch somefile
   ```

   脚本文件可以包含任意数量的命令。为方便起见，此示例脚本只有单个 `touch` 命令。

以下配方执行该脚本。

```
cookbook_file "/tmp/touchfile" do
  source "touchfile"
  mode 0755
end

execute "touchfile" do
  user "root"
  cwd "/tmp"
  command "./touchfile"
end
```

`cookbook_file` 资源会将脚本文件复制到 `/tmp`，然后设置模式，以使该文件可执行。`execute` 资源随后会按如下所示执行文件：
+ `user` 属性指定命令的用户 (在此示例中为 `root`)。
+ `cwd` 属性指定工作目录 (在此示例中为 `/tmp`)。
+ `command` 属性指定要执行的脚本 (在此示例中为 `touchfile`)，该脚本位于工作目录中。

**运行配方**

1. 将 `recipes/default.rb` 中的代码替换为前面的示例。

1. 运行 `kitchen converge`，然后登录到实例，以验证 `/tmp` 现在是否包含脚本文件 (模式设置为 0755) 以及 `somefile`。

完成后，运行 `kitchen destroy` 以关闭实例。下一节将使用新的说明书。