Ansible教程:Ad-hoc 命令用法-copy模块详解 作者:马育民 • 2026-09-22 14:17 • 阅读:10001 # 介绍 copy模块:**把本地文件/内容复制到远程主机** **注意:**和`fetch`相反,fetch是拉取远程到本地 # copy模块参数 | 参数 | 说明 | |---|---| | **`src`** | **本地源文件路径**(ansible控制机上的文件);若是目录,末尾加`/`代表复制目录内所有文件,不加`/`则复制目录本身 | | **`dest`** | **远程目标路径**,必须写;如果src是文件,dest可以是目录(文件放到这个目录下) | | `content` | 直接指定文本内容,**替代src**,把内容写入远程文件,不用准备本地文件 | | `owner` | 远程文件属主 | | `group` | 远程文件属组 | | `mode` | 远程文件权限,推荐用数字如`644` | | `backup` | yes/no,默认no;`yes`:如果远程文件已存在,先备份一份(带时间戳)再覆盖 | | `force` | yes/no,默认yes;yes:内容不同就覆盖;no:目标文件存在就不覆盖 | # 例子1:推送本地文件到被控机 ### 创建文件 切换到家目录: ``` cd ~ ``` 创建文件: ``` vim test.sh ``` 输入内容: ``` #!/bin/bash echo "控制机上的文件" ``` 测试脚本是否可用: ``` bash test.sh ``` ### 把文件发送到被控制机 ```bash ansible all -m copy -a "src=~/test.sh dest=~/" -i ansible_client.ini ``` **解释:** dest末尾带`/`,代表放到这个目录;如果写`dest=~/test2.sh`,则重命名。 ### 登录被控制机查看文件 登录控制机查看文件 运行脚本: ``` bash test.sh ``` ### 在主控机运行被控机脚本 ##### command模块运行 ``` ansible all -m command -a "bash ~/test.sh" -i ansible_client.ini ``` ##### shell 模块运行 ``` ansible all -m shell -a "bash ~/test.sh" -i ansible_client.ini ``` ### 推送并重命名 ```bash ansible all -m copy -a "src=~/test.sh dest=~/test2.sh" -i ansible_client.ini ``` # 例子2. 在被控机写入文本内容 修改被控机 `test.sh` 文件的内容(覆盖修改),修改内容如下: ``` echo "新内容" echo "新内容2222" ``` ### 命令 ```bash ansible all -m copy -a 'content="echo \"新内容\"\necho \"新内容2222\"" dest=~/test.sh mode=744' -i ansible_client.ini ``` **解释:** - 换行用 `\n`;参数里有引号,外层建议单引号包裹。 - mode:修改权限 ### 查看被控机文件内容 登录被控机,查看文件内容: ``` cat test.sh ``` 由于修改权限,可执行运行脚本: ``` ./test.sh ``` # 例子3. 推送,存在旧文件先备份 ### 修改主控机的 test.sh 文件 必须修改内容,如果内容一样,不会备份 ``` vim test.sh ``` 修改内容为: ``` #!/bin/bash echo "控制机上的文件11111111" ``` ### 发送命令 ```bash ansible all -m copy -a "src=~/test.sh dest=~/test.sh backup=yes" -i ansible_client.ini ``` 执行结果如下: [](https://www.malaoshi.top/upload/0/3/1GW45wVDMbw5.png) ### 查看被控机 远程被控机会生成类似:`test.sh.38317.2026-09-22@09:24:48~`备份文件,如下: [](https://www.malaoshi.top/upload/0/3/1GW45wW1jwfA.png) # 例子4. 指定属主、属组、权限 ```bash ansible all -m copy -a "src=~/test.sh dest=/home/user/test3.sh owner=root group=root mode=777" -i ansible_client.ini -b -K ``` **解释:** - `-b`:ubuntu系统中,默认不允许使用 `root` 用户,所以设置文件的所属用户为 `root`,需要使用 `root` 权限,相当于执行 `sudo` 命令 - `-K`:输入 `root` 用户的密码 # 例子5. 不强制覆盖,远程文件存在就跳过 `force=no` 表示不强制覆盖 ```bash ansible all -m copy -a "src=~/test.sh dest=~/ force=no" -i ansible_client.ini ``` 执行结果如下图,显示 `false` 表示文件没改变: [](https://www.malaoshi.top/upload/0/3/1GW45xjg8GND.png) # 例子6. 远程主机内部复制文件 `remote_src=yes` 不是控制机推送!是将被控机 `~/test.sh` 复制到 `/tmp` 目录下 ```bash ansible all -m copy -a "src=~/test.sh dest=/tmp remote_src=yes" -i ansible_client.ini ``` # 例子7. 推送目录 ### 末尾带 / `src=/tmp/conf/` 末尾带 `/`:复制 `conf` 目录里面所有文件到远程 `/opt/conf` ```bash ansible all -m copy -a "src=/tmp/conf/ dest=/opt/conf" ``` ### 不带 / `src=/tmp/conf` 不带 `/`:把整个 `conf` 目录复制到远程 `/opt/conf` ``` ansible all -m copy -a "src=/tmp/conf dest=/opt/" ``` # 常用附加参数 ```bash # 指定ssh用户 ansible web -m copy -a "xxx" -u root # 使用sudo提权 ansible web -m copy -a "xxx" -u admin -b # -b == --become,提权;-K 手动输入sudo密码 ansible web -m copy -a "xxx" -u admin -b -K ``` # 常见坑 1. `mode` 写 `644` 最好写成 `0644`,部分ansible版本会识别错误 2. src是**控制节点本地**,不是远程机器,很多新手搞混 3. 目录复制时`src`末尾`/`有无,行为完全不一样 4. copy模块会自动校验文件md5,如果文件内容没变,不会执行操作(幂等性) 5. 目标目录不存在会报错!需要先`file`模块创建目录,或者在playbook搭配`state=directory`,Ad-hoc可单独执行: ```bash ansible web -m file -a "path=/opt/conf state=directory" ``` 原文出处:/show_1GW45wYrhbCH.html