Ansible教程:Ad-hoc 命令用法-copy模块详解

介绍

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

把文件发送到被控制机

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

推送并重命名

ansible all -m copy -a "src=~/test.sh  dest=~/test2.sh"  -i ansible_client.ini

例子2. 在被控机写入文本内容

修改被控机 test.sh 文件的内容(覆盖修改),修改内容如下:

echo "新内容"
echo "新内容2222"

命令

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"

发送命令

ansible all -m copy -a "src=~/test.sh  dest=~/test.sh backup=yes"  -i ansible_client.ini

执行结果如下:

查看被控机

远程被控机会生成类似:test.sh.38317.2026-09-22@09:24:48~备份文件,如下:

例子4. 指定属主、属组、权限

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 表示不强制覆盖

ansible all -m copy -a "src=~/test.sh  dest=~/ force=no"  -i ansible_client.ini

执行结果如下图,显示 false 表示文件没改变:

例子6. 远程主机内部复制文件

remote_src=yes 不是控制机推送!是将被控机 ~/test.sh 复制到 /tmp 目录下

ansible all -m copy -a "src=~/test.sh  dest=/tmp  remote_src=yes"  -i ansible_client.ini

例子7. 推送目录

末尾带 /

src=/tmp/conf/ 末尾带 /:复制 conf 目录里面所有文件到远程 /opt/conf

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/"

常用附加参数

# 指定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可单独执行:
    ansible web -m file -a "path=/opt/conf state=directory"
    

原文出处:/show_1GW45wYrhbCH.html