news 2026/1/13 15:35:09

02-Ansible 基本使用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
02-Ansible 基本使用

文章目录

  • 02-Ansible 基本使用
    • Ansible 清单
      • Ansible 软件包中文件
      • 主机清单
      • 静态主机清单
        • 最简单的静态清单
        • 主机组
        • 主机组嵌套
        • 范围简写
      • 动态主机清单
        • ansible-inventory 命令
    • 管理 ANSIBLE 配置文件
      • 配置文件位置和优先级
      • 配置文件解析
      • 配置文件示例
      • ansible-config 命令
        • ansible-config view
        • ansible-config dump
        • ansible-config list
      • localhost 连接
    • 运行 AD HOC 命令
      • 实验环境
      • ansible AD HOC 命令
      • Ansible 部分模块
      • 基础执行(command/shell 模块)
      • ansible-doc 命令
      • command模块
      • shell 模块
      • raw 模块
      • ansible AD HOC 命令选项

02-Ansible 基本使用

Ansible 清单

Ansible 软件包中文件

[dyx@controller ~]# rpm -ql ansible
  • 配置文件目录 /etc/ansible

  • 执行文件目录 /usr/bin

  • lib依赖库目录 /usr/lib/python2.7/site-packages/ansible

  • 插件 /usr/share/ansible/plugins

  • Help文档目录 /usr/share/doc/ansible

  • Man文档目录/usr/share/man/man1/

主机清单

Inventory 定义Ansible将要管理的一批主机。这些主机也可以分配到组中,以进行集中管理 组可以包含

子组,主机也可以是多个组的成员。清单还可以设置应用到它所定义的主机和组的变量。

通过以下方式定义主机清单:

  • **静态主机清单:**以文本文件的方式来定义。

  • **动态主机清单:**使用外部信息提供程序通过脚本或其他程序来自动生成。目的是从启动环境中获取主机清单,例如openstack、kubernetes、zabbix等。

静态主机清单

主机清单支持多种格式,例如ini、yaml、脚本等。

本次课程使用 ini 格式。

最简单的静态清单

受管节点的主机名或IP地址的列表,每行一个。

示例:

[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventoryweb1.example.com web2.example.com db1.example.com db2.example.com192.168.0.42

验证主机是否在inventory中

[dyx@controller ~]# ansible --list-hosts -i inventory web1.example.comhosts(1): web1.example.com[dyx@controller ~]# ansible --list-hosts -i inventory 192.168.0.42hosts(1):192.168.0.42

ansible命令通过–inventory PATHNAME或-i PATHNAME选项在命令行中指定清单文件的位置,其中PATHNAME是所需清单文件的路径。

主机组

还可以将受管节点组织为主机组。通过主机组,更加有效地对一系列系统运行Ansible。

格式:

[groupname]hostnamehostip

示例:

[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventoryapp1.examlpe.com[webservers]web1.example.com web2[dbservers]db1.example.com db2.example.com192.0.2.42192.0.2.3

验证:

[dyx@controller ~]# ansible --list-hosts -i inventory webservershosts(2): web1.example.com web2# 注意:192.0.2.43属于dbservers组[dyx@controller ~]# ansible --list-hosts -i inventory dbservershosts(4): db1.example.com db2.example.com192.0.2.42192.0.2.3

有两个组总是存在的:

  • all:包含inventory中所有主机。

  • ungrouped:inventory中列出的,但不属于任何组的主机。

验证:

[dyx@controller ~]# ansible --list-hosts -i inventory allhosts(7): app1.examlpe.com web1.example.com web2 db1.example.com db2.example.com192.0.2.42192.0.2.3[dyx@controller ~]# ansible --list-hosts -i inventory ungroupedhosts(1): app1.examlpe.com

根据需要,将主机分配在多个组中,例如根据主机的角色、其物理位置以及是否在生产环境中等因素。

[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventory[webservers]web1.example.com web2192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2 db2

验证:

[dyx@controller ~]# ansible --list-hosts -i inventory webservershosts(3): web1.example.com web2192.168.3.7[dyx@controller ~]# ansible --list-hosts -i inventory eastdchosts(2): web1.example.com db1.example.com
主机组嵌套

一个主机组还可以属于另外一个主机组。

示例:

[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventory[webservers]web1.example.com web2192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2 db2[dc:children]eastdc westdc

验证:

[dyx@controller ~]# ansible --list-hosts -i inventory dchosts(4): web1.example.com db1.example.com web2 db2

子组中的主机组必须定义,否则会出现语法上的报错。

示例:

[dyx@controller ~]# vim inventory[dyx@controller ~]# cat inventory[webservers]web1.example.com web2192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2 db2[dc:children]eastdc westdc`node1`

验证:

torydc[WARNING]: * Failed to parse /dyx/inventory with yaml plugin: We were unable toreadeither as JSON nor YAML, these are the errors we got from each: JSON: No JSON object could be decoded Syntax Errorwhileloading YAML. did notfindexpected<document start>The error appears to bein'/root/inventory':line2,column1, but may be elsewhereinthefiledepending on the exact syntax problem. The offending line appears to be:[webservers]web1.example.com ^ here[WARNING]: * Failed to parse /root/inventory with ini plugin: /root/inventory:22: Section[dc:children]includes undefined group: node[WARNING]: Unable to parse /root/inventory as an inventorysource[WARNING]: No inventory was parsed, only implicit localhost is available[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match'all'hosts(4): web1.example.com db1.example.com web2 db2
范围简写

通过指定主机名称或IP地址的范围来简化Ansible主机清单。您可以指定数字或字母范围。

语法:[start:end]

示例:

[dyx@controller ~]# vim inventory# 代表192.168.4.0-192.168.7.255[priv]192.168.[4:7].[0:255]#代表01,02...10[hosts]host[01:10].example.com# 代表a b c[servers]server[a:c].example.com

验证:

[dyx@controller ~]# ansible --list-hosts -i inventory hostshosts(10): host01.example.com host02.example.com host03.example.com host04.example.com host05.example.com host06.example.com host07.example.com host08.example.com host09.example.com host10.example.com[dyx@controller ~]# ansible --list-hosts -i inventory servershosts(3): servera.example.com serverb.example.com serverc.example.com

以下是错误的范围示例:

[dyx@controller ~]# vim inventory[servers]server[0a:2c].example.com

验证:

[dyx@controller ~]# ansible --list-hosts -i inventory all[WARNING]: * Failed to parse /root/inventory with yaml plugin: We were unable toreadeither as JSON nor YAML, these are the errors we got from each: JSON: No JSON object could be decoded Syntax Errorwhileloading YAML. did notfindexpected<document start>The error appears to bein'/root/inventory':line2,column1, but may be elsewhereinthefiledepending on the exact syntax problem. The offending line appears to be:[serevers]server[0a:2c].example.com ^ here[WARNING]: * Failed to parse /root/inventory with ini plugin: invalid literalforint()with base10:`'0a'`[WARNING]: Unable to parse /root/inventory as an inventorysource[WARNING]: No inventory was parsed, only implicit localhost is available[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match'all'hosts(0):

动态主机清单

使用外部数据提供的信息动态生成Ansible清单信息。

本课程内容不做进一步讨论。

ansible-inventory 命令

通过不同的格式查看清单文件。

[dyx@controller ~]# ansible-inventory --helpusage: ansible-inventory[-h][--version][-v][-i INVENTORY][--vault-id VAULT_IDS][--ask-vault-pass|--vault-password-file VAULT_PASSWORD_FILES][--playbook-dir BASEDIR][--list][--host HOST][--graph][-y][--toml][--vars][--export][--output OUTPUT_FILE][host|group]positional arguments:host|group optional arguments: --ask-vault-pass askforvault password --export When doing an --list, representina way that is optimizedforexport,not as an accurate representation of how Ansible has processed it --output OUTPUT_FILE When doing --list, send the inventory to afileinstead of to thescreen--playbook-dir BASEDIR Since this tool does not use playbooks, use this as a substitute playbook directory.This sets the relative pathformany features including roles/ group_vars/ etc. --toml Use TOMLformatinstead of default JSON, ignoredfor--graph --vars Add vars to graph display, ignored unless used with --graph --vault-id VAULT_IDS the vault identity to use --vault-password-file VAULT_PASSWORD_FILES vault passwordfile--version show program's version number, configfilelocation, configured module search path, module location, executable location andexit-h, --help show thishelpmessage andexit-i INVENTORY, --inventory INVENTORY, --inventory-file INVENTORY specify inventoryhostpath or comma separatedhostlist. --inventory-file is deprecated -v, --verbose verbose mode(-vvvformore, -vvvv toenableconnection debugging)-y, --yaml Use YAMLformatinstead of default JSON, ignoredfor--graph Actions: One of following must be used on invocation, ONLY ONE!--graph create inventory graph,ifsupplying pattern it must be a valid group name --host HOST Output specifichostinfo, works as inventory script --list Output all hosts info, works as inventory script Show Ansible inventory information, by default it uses the inventory script JSONformat

示例清单:

[dyx@controller ~]# vim inventoryapp1.example.com[webservers]web1.example.com web2.example.com192.168.3.7[dbservers]db1.example.com db2.example.com192.0.2.42[eastdc]web1.example.com db1.example.com[westdc]web2.example.com db2.example.com[dc:children]eastdc westdc

验证:

# 树形结构显示[dyx@controller ~]# ansible-inventory -i inventory --graph@all:|--@dbservers:||--192.0.2.42||--db1.example.com||--db2.example.com|--@dc:||--@eastdc:|||--db1.example.com|||--web1.example.com||--@westdc:|||--db2.example.com|||--web2.example.com|--@ungrouped:||--app1.example.com|--@webservers:||--192.168.3.7||--web1.example.com||--web2.example.com# yaml格式显示[dyx@controller ~]# ansible-inventory -i inventory --list -yall: children: dbservers: hosts:192.0.2.42:{}db1.example.com:{}db2.example.com:{}dc: children: eastdc: hosts: db1.example.com:{}web1.example.com:{}westdc: hosts: db2.example.com:{}web2.example.com:{}ungrouped: hosts: app1.example.com:{}webservers: hosts:192.168.3.7:{}web1.example.com:{}web2.example.com:{}

管理 ANSIBLE 配置文件

配置文件位置和优先级

  1. 环境变量 ANSIBLE_CONFIG
  2. ./ansible.cfg,当前位置中的 ansible.cfg,当前位置一般是项目目录。
  3. ~/.ansible.cfg
  4. /etc/ansible/ansible.cfg

从上到下,优先级越来越低。

建议:在当前目录下定义ansible.cfg文件。

验证优先级

# 环境准备[dyx@controller ~]$mkdirweb&&cdweb# 查看ansible命令当前使用的配置文件[dyx@controller web]$ ansible --version ansible2.9.27 configfile=`/etc/ansible/ansible.cfg`configured module search path=[u'/home/dyx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']ansible python module location=/usr/lib/python2.7/site-packages/ansible executable location=/bin/ansible python version=2.7.5(default, Oct142020,14:45:30)[GCC4.8.520150623(Red Hat4.8.5-44)]# 或者[dyx@controller web]$ ansible --version|grep'config file'configfile=/etc/ansible/ansible.cfg[dyx@controller web]$touch~/.ansible.cfg[dyx@controller web]$ ansible --version|grep'config file'configfile=/home/dyx/.ansible.cfg[dyx@controller web]$touchansible.cfg[dyx@controller web]$ ansible --version|grep'config file'configfile=/home/dyx/web/ansible.cfg[dyx@controller web]$exportANSIBLE_CONFIG=/opt/ansible.cfg[dyx@controller web]$sudotouch/opt/ansible.cfg[dyx@controller web]$ ansible --version|grep'config file'configfile=/opt/ansible.cfg[dyx@controller web]$unsetANSIBLE_CONFIG[dyx@controller web]$ ansible --version|grep'config file'configfile=/home/dyx/web/ansible.cfg

配置文件解析

ansible 默认配置文件 /etc/ansible/ansible.cfg。

Ansible 配置文件包括以下部分:

[dyx@controller web]$grep"^\["/etc/ansible/ansible.cfg[defaults][inventory][privilege_escalation][paramiko_connection][ssh_connection][persistent_connection][accelerate][selinux][colors][diff]

常用参数解析如下:

[defaults]# inventory 指定清单文件路径inventory=/etc/ansible/hosts# 并发执行同一个任务的主机数量forks=5# ansible检查任务是否执行完成的时间间隔poll_interval=15# 连接登录到受管主机时是否提示输入密码ask_pass=True# 控制facts如何收集# smart - 如果facts已经收集过了,就不收集了。# implicit - facts收集,剧本中使用gather_facts: False关闭facts收集。# explicit - facts不收集,剧本中使用gather_facts: True关闭facts收集。gathering=implicit# 收集facts范围# all - gather all subsets# network - gather min and network facts# hardware - gather hardware facts (longest facts to retrieve)# virtual - gather min and virtual facts# facter - import facts from facter# ohai - import facts from ohai# You can combine them using comma (ex: network,virtual)# You can negate them using ! (ex: !hardware,!facter,!ohai)# A minimal set of facts is always gathered.gather_subset=all# 收集facts超时时间gather_timeout=10# 变量注入,通过ansible_facts引用inject_facts_as_vars=True# 定义角色路径,以冒号分隔roles_path=/etc/ansible/roles# SSH是否检验 host keyhost_key_checking=False# 连接登录到受管主机时使用的用户身份remote_user=root# ansible 命令和ansible-playbook 命令输出内容存放位置log_path=/var/log/ansible.log# ansible 命令默认模块module_name=command# ssh 私钥文件位置private_key_file=/path/to/file# 默认ansible-vault命令的密码文件vault_password_file=/path/to/vault_password_file# 定义ansible_managed变量值ansible_managed=Ansible managed# 剧本执行过程中,遇到未定义的变量不报错error_on_undefined_vars=False# 系统告警启用system_warnings=True# 下架告警启用deprecation_warnings=True# 使用command和shell模块时,是否提示告警command_warnings=False# facts保存在哪里,例如redisfact_caching=memory[inventory]# 启用的清单插件, 默认为: 'host_list', 'script', 'auto', 'yaml', 'ini', 'toml'#enable_plugins = host_list, virtualbox, yaml, constructed# 当清单源是一个目录的时候,忽略这些后缀的清单文件#ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini,.cfg, .retry[privilege_escalation]# 连接到受管主机后是否需要进行权限提升或切换用户become=True# 使用何种方式进行用户切换或提权become_method=sudo# 用户切换或提权后的对应用户become_user=root# 进行用户切换或提权时是否提示输入密码become_ask_pass=False

说明:“#” 和 ";"开头的行,作为注释

配置文件示例

对于基本操作, 使用[defaults][privilege_escalation]即可。

配置文件示例

[dyx@controller web]$vimansible.cfg[dyx@controller web]$catansible.cfg[defaults]remote_user=dyxinventory=./inventory[privilege_escalation]become=truebecome_user=rootbecome_method=sudobecome_ask_pass=false

编辑inventory

[dyx@controller web]$viminventory[dyx@controller web]$catinventory node[1:4]

最终效果:

[dyx@controller web]$ ansible all -ahostnamenode4|CHANGED|rc=0>>node4.dyx.cloud node2|CHANGED|rc=0>>node2.dyx.cloud node3|CHANGED|rc=0>>node3.dyx.cloud node1|CHANGED|rc=0>>node1.dyx.cloud

ansible-config 命令

用于分析ansible命令的配置。

[dyx@controller web]$ ansible-config -h usage: ansible-config[-h][--version][-v]{list,dump,view}... View ansible configuration. positional arguments:{list,dump,view}`list Print all config options``dump Dump configuration``view View configurationfile`optional arguments: --version show program's version number, configfilelocation, configured module search path, module location, executable location andexit-h, --help show thishelpmessage andexit-v, --verbose verbose mode(-vvvformore, -vvvv toenableconnection debugging)
ansible-config view

查看当前ansible配合文件内容。

[dyx@controller web]$ ansible --version|grepfileconfigfile=/home/dyx/web/ansible.cfg[dyx@controller web]$ ansible-config view[defaults]remote_user=dyxinventory=./inventory[privilege_escalation]become=truebecome_user=rootbecome_method=sudobecome_ask_pass=false
ansible-config dump

当前ansible生效的所有配置,包括所有默认值

[dyx@controller web]$ ansible-config dump ACTION_WARNINGS(default)=True AGNOSTIC_BECOME_PROMPT(default)=True ALLOW_WORLD_READABLE_TMPFILES(default)=False ANSIBLE_CONNECTION_PATH(default)=None ANSIBLE_COW_PATH(default)=None ANSIBLE_COW_SELECTION(default)=default ANSIBLE_COW_WHITELIST(default)=['bud-frogs','bunny','cheese','daemon','default','d ANSIBLE_FORCE_COLOR(default) = False ANSIBLE_NOCOLOR(default) = False ANSIBLE_NOCOWS(default) = False ANSIBLE_PIPELINING(default) = False ANSIBLE_SSH_ARGS(default) = -C -o ControlMaster=auto -o ControlPersist=60s ANSIBLE_SSH_CONTROL_PATH(default) = None ANSIBLE_SSH_CONTROL_PATH_DIR(default) = ~/.ansible/cp ANSIBLE_SSH_EXECUTABLE(default) = ssh ANSIBLE_SSH_RETRIES(default) = 0 ANY_ERRORS_FATAL(default) = False BECOME_ALLOW_SAME_USER(default) = False BECOME_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/become', u'/usr/share/ansible CACHE_PLUGIN(default)=memory CACHE_PLUGIN_CONNECTION(default)=None CACHE_PLUGIN_PREFIX(default)=ansible_facts CACHE_PLUGIN_TIMEOUT(default)=86400COLLECTIONS_PATHS(default)=[u'/home/dyx/.ansible/collections', u'/usr/share/ansible/col COLOR_CHANGED(default) = yellow COLOR_CONSOLE_PROMPT(default) = white COLOR_DEBUG(default) = dark gray COLOR_DEPRECATE(default) = purple COLOR_DIFF_ADD(default) = green COLOR_DIFF_LINES(default) = cyan COLOR_DIFF_REMOVE(default) = red COLOR_ERROR(default) = red COLOR_HIGHLIGHT(default) = white COLOR_OK(default) = green COLOR_SKIP(default) = cyan COLOR_UNREACHABLE(default) = bright red COLOR_VERBOSE(default) = blue COLOR_WARN(default) = bright purple COMMAND_WARNINGS(default) = True CONDITIONAL_BARE_VARS(default) = True CONNECTION_FACTS_MODULES(default) = {'iosxr': 'iosxr_facts', 'voss': 'voss_facts', 'cisco COVERAGE_REMOTE_OUTPUT(default)=None COVERAGE_REMOTE_WHITELIST(default)=* DEFAULT_ACTION_PLUGIN_PATH(default)=[u'/home/dyx/.ansible/plugins/action', u'/usr/share DEFAULT_ALLOW_UNSAFE_LOOKUPS(default) = False DEFAULT_ASK_PASS(default) = False DEFAULT_ASK_VAULT_PASS(default) = False DEFAULT_BECOME(/home/dyx/web/ansible.cfg) = True DEFAULT_BECOME_ASK_PASS(/home/dyx/web/ansible.cfg) = False DEFAULT_BECOME_EXE(default) = None DEFAULT_BECOME_FLAGS(default) = DEFAULT_BECOME_METHOD(/home/dyx/web/ansible.cfg) = sudo DEFAULT_BECOME_USER(/home/dyx/web/ansible.cfg) = root DEFAULT_CACHE_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/cache', u'/usr/share/a DEFAULT_CALLABLE_WHITELIST(default)=[]DEFAULT_CALLBACK_PLUGIN_PATH(default)=[u'/home/dyx/.ansible/plugins/callback', u'/usr/s DEFAULT_CALLBACK_WHITELIST(default) = [] DEFAULT_CLICONF_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/cliconf', u'/usr/sha DEFAULT_CONNECTION_PLUGIN_PATH(default)=[u'/home/dyx/.ansible/plugins/connection', u'/u DEFAULT_DEBUG(default) = False DEFAULT_EXECUTABLE(default) = /bin/sh DEFAULT_FACT_PATH(default) = None DEFAULT_FILTER_PLUGIN_PATH(default) = [u'/home/dyx/.ansible/plugins/filter', u'/usr/share
ansible-config list

查看所有配置参数用途,配置位置等。

[dyx@controller web]$ ansible-config list ACTION_WARNINGS: default:truedescription:[By default Ansible will issue a warning when received from a task action(module or action plugin), These warnings can be silenced by adjusting this setting to False.]env: -{name: ANSIBLE_ACTION_WARNINGS}ini: -{key: action_warnings, section: defaults}name: Toggle action warnings type: boolean version_added:'2.5'AGNOSTIC_BECOME_PROMPT: default:truedescription: Display an agnostic become prompt instead of displaying a prompt containin thecommandline supplied become method env: -{name: ANSIBLE_AGNOSTIC_BECOME_PROMPT}ini: -{key: agnostic_become_prompt, section: privilege_escalation}name: Display an agnostic become prompt type: boolean version_added:'2.5'yaml:{key: privilege_escalation.agnostic_become_prompt}ALLOW_WORLD_READABLE_TMPFILES:

localhost 连接

默认Ansible连接到受管主机的协议为 smart (通常采用最有效的方式 - SSH)。如本地清单中并未指定localhost,Ansible会隐式设置

localhost,并使用local连接类型连接localhost。

local连接类型会忽略remote_user的设置,并且直接在本地系统上运行命令。

如果使用了特权提升,此时ansible将会在运行sudo时使用运行Ansible命令的账户的身份进行提权,而非remote_user所指定的账户。

更改localhost连接方式:清单中包涵 localhost。

运行 AD HOC 命令

实验环境

[laogao@controller ~]$mkdirweb&&cdweb[laogao@controller web]$cat>ansible.cfg<<'EOF' [defaults] remote_user = laogao inventory = ./inventory [privilege_escalation] become = True become_user = root become_method = sudo become_ask_pass = False EOF[laogao@controller web]$cat>inventory<<'EOF' node1 node2 node3 node4 EOF

ansible AD HOC 命令

命令作用

快速执行单个Ansible任务,而不需要将它保存下来供以后再次运行。它们是简单的在线操作,无需编写playbook即可运行。

**快速测试和更改很有用。**例如,您可以使用临时命令确保一组服务器上的/ etc/hosts文件中存在某一特定的行。您可以使用另一个临时

命令在许多不同的计算机上高效重启一项服务,或者确保特定的软件包为最新版本。

命令语法

ansible host-pattern -m module[-a'module arguments'][-i inventory]
  • host-pattern,是inventory中定义的主机或主机组,可以为ip、hostname、inventory中的group组名、具有“,”或“*”或“:”等特殊字符的匹配型字符串,是必选项。

  • -m module,module是一个小程序,用于实现具体任务。

  • -a ‘module arguments’,是模块的参数。

  • -i inventory,指定inventory文件。

命令执行结果颜色说明

Ansible的返回结果都非常友好,用3种颜色来表示执行结果:

  • 红色:表示执行过程有异常,一般会中止剩余所有的任务。

  • 绿色:表示目标主机已经是预期状态,不需要更改 。

  • 黄色:表示命令执行结束后目标有状态变化,并设置为预期状态,所有任务均正常执行。

Ansible 部分模块

Ansible 模块存放位置:/usr/lib/python*/site-packages/ansible

官网:https://docs.ansible.com/projects/ansible/latest/collections/index_module.html。

  • 文件模块

    • copy: 将控制主机上的文件复制到受管节点,类似于scp
    • file: 设置文件的权限和其他属性
    • lineinfile: 确保特定行是否在文件中
    • synchronize: 使用rsync将控制主机上的文件同步到受管节点
  • 软件包模块

    • package: 自动检测操作系统软件包管理器
    • yum: 使用 YUM 软件包管理器管理软件包
    • apt: 使用 APT 软件包管理器管理软件包
    • gem: 管理 Rubygem
    • pip: 从 PyPI 管理 Python 软件包
  • 系统模块

    • ansible.posix.firewalld: 使用firewalld管理任意端口和服务
    • reboot: 重新启动计算机
    • service: 管理服务
    • user、group: 管理用户和组帐户
  • NetTools模块

    • get_url: 通过HTTP、HTTPS或FTP下载文件
    • nmcli: 管理网络
    • uri: 与 Web 服务交互

ansible AD HCO命令案例:

基础执行(command/shell 模块)

command是默认模块(无需显式指定 -m ),适用于执行shell特性(管道、重定向、环境变量)的简单命令

示例 1:查看远程主机主机名

[dyx@controller web]$ ansible all -mcommand-a"hostname"node2|CHANGED|rc=0>>node2.dyx.cloud node4|CHANGED|rc=0>>node4.dyx.cloud node3|CHANGED|rc=0>>node3.dyx.cloud node1|CHANGED|rc=0>>node1.dyx.cloud[dyx@controller web]$ ansible all -a"hostname"node2|CHANGED|rc=0>>node2.dyx.cloud node4|CHANGED|rc=0>>node4.dyx.cloud node3|CHANGED|rc=0>>node3.dyx.cloud node1|CHANGED|rc=0>>node1.dyx.cloud

示例 2:检查远程主机操作系统版本

[dyx@controller web]$ ansible all -mcommand-a"cat /etc/os-release"[dyx@controller web]$ ansible all -a"cat /etc/os-release"

示例 3:查看远程主机内存使用情况

[dyx@controller web]$ ansible all -a"free -h"node2|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 472M1.2G 12M 312M1.3G Swap:3.9G 0B3.9G node3|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 475M1.2G 12M 311M1.3G Swap:3.9G 0B3.9G node4|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 479M1.2G 12M 312M1.3G Swap:3.9G 0B3.9G node1|CHANGED|rc=0>>total usedfreeshared buff/cache available Mem:1.9G 474M1.2G 12M 311M1.3G Swap:3.9G 0B3.9G

示例 4:统计远程主机指定目录文件数量

# 注:这里ls+wc是两个命令,但未用管道符(command不支持管道),实际是执行`ls -l /var/log/nginx`后通过wc统计,若需管道需用shell模块[dyx@controller web]$ ansible all -a"ls -l /etc |wc -l"[dyx@controller web]$ ansible all -m shell -a"ls -l /etc |wc -l"node2|CHANGED|rc=0>>276node4|CHANGED|rc=0>>276node3|CHANGED|rc=0>>276node1|CHANGED|rc=0>>276

示例 5:创建空文件

[dyx@controller web]$ ansible all -a"touch /tmp/ansible_test.txt"[WARNING]: Consider using thefilemodule withstate=touch rather than running'touch'.If you need to usecommandbecausefileis insufficient you canadd'warn: false'to thiscommandtask orset'command_warnings=False'inansible.cfg to get rid of this message. node3|CHANGED|rc=0>>node2|CHANGED|rc=0>>node4|CHANGED|rc=0>>node1|CHANGED|rc=0>>

示例 6:检查远程服务进程

[dyx@controller web]$ ansible all -a"ps aux"# ✅ 正确:仅执行ps aux,后续过滤可在本地处理ansible all -a"ps aux | grep sshd"# ❌ 错误:command不支持管道,需改用shell[dyx@controller web]$ ansible all -m shell -a"ps aux |grep sshd"node2|CHANGED|rc=0>>root12180.00.21129004316? Ss12:240:00 /usr/sbin/sshd -D root19030.00.31679486784? Ss12:250:00 sshd: root@pts/0 root40570.00.21567765584? Ss15:360:00 sshd: dyx[priv]dyx40600.00.11570882824? S15:360:00 sshd: dyx@pts/1 root53060.00.01132801192pts/1 S+15:390:00 /bin/sh -cpsaux|grepsshd root53080.00.0112812940pts/1 S+15:390:00grepsshd node4|CHANGED|rc=0>>root12180.00.21129004316? Ss12:240:00 /usr/sbin/sshd -D root19060.00.31679486780? Ss12:250:00 sshd: root@pts/0 root40500.00.21567765588? Ss15:360:00 sshd: dyx[priv]dyx40540.00.11570882816? S15:360:00 sshd: dyx@pts/1 root52980.00.01132801192pts/1 S+15:400:00 /bin/sh -cpsaux|grepsshd root53000.00.0112812940pts/1 S+15:400:00grepsshd node3|CHANGED|rc=0>>root12180.00.21129004312? Ss12:240:00 /usr/sbin/sshd -D root19080.00.31679486780? Ss12:250:00 sshd: root@pts/0 root40020.00.21567765584? Ss15:360:00 sshd: dyx[priv]dyx40060.00.11570882820? S15:360:00 sshd: dyx@pts/1 root52500.00.01132801192pts/1 S+15:400:00 /bin/sh -cpsaux|grepsshd root52520.00.0112812940pts/1 S+15:400:00grepsshd node1|CHANGED|rc=0>>root12090.00.21129004316? Ss12:240:00 /usr/sbin/sshd -D root19040.00.31679486776? Ss12:250:00 sshd: root@pts/0 root39810.00.21567765592? Ss15:360:00 sshd: dyx[priv]dyx39840.00.11570882820? S15:360:00 sshd: dyx@pts/1 root52320.00.01132801192pts/1 S+15:400:00 /bin/sh -cpsaux|grepsshd root52340.00.0112812944pts/1 S+15:400:00grepsshd

示例 7:查看远程主机磁盘挂载信息

ansible all -a"mount | grep /sys"# ❌ 错误:含管道,改用shell[dyx@controller web]$ ansible all -a"mount"# ✅ 正确:查看所有挂载,本地筛选/sys

示例 8:验证远程主机端口连通性(基础版)

# 检查80端口是否监听(需安装nc)[dyx@controller web]$ ansible all -a"nc -zv 127.0.0.1 22"node3|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds. node1|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds. node2|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds. node4|CHANGED|rc=0>>Ncat: Version7.50(https://nmap.org/ncat)Ncat: Connected to127.0.0.1:22. Ncat:0bytes sent,0bytes receivedin0.01seconds.

示例 9:查看远程主机指定文件的最后 10 行

ansible all -a"tail -10 /var/log/messages"

示例 10:查看IP地址

[dyx@controller web]$ ansible all -a"ip -br a"node1|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.11/24 fe80::9f3f:8d41:73d1:d531/64 fe80::af36:4fe7:4616:f9d6/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN node3|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.13/24 fe80::af36:4fe7:4616:f9d6/64 fe80::9f3f:8d41:73d1:d531/64 fe80::8c56:cea:5e7a:8aa5/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN node2|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.12/24 fe80::af36:4fe7:4616:f9d6/64 fe80::9f3f:8d41:73d1:d531/64 fe80::8c56:cea:5e7a:8aa5/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN node4|CHANGED|rc=0>>lo UNKNOWN127.0.0.1/8 ::1/128 ens33 UP192.168.108.14/24 fe80::af36:4fe7:4616:f9d6/64 fe80::9f3f:8d41:73d1:d531/64 fe80::8c56:cea:5e7a:8aa5/64 virbr0 DOWN192.168.122.1/24 virbr0-nic DOWN

ansible-doc 命令

[dyx@controller web]$ ansible-doc -h usage: ansible-doc[-h][--version][-v][-M MODULE_PATH][--playbook-dir BASEDIR][-t{become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}][-j][-F|-l|-s|--metadata-dump][plugin[plugin...]]plugin documentation tool positional arguments: plugin Plugin optional arguments: --metadata-dump **For internal testing only** Dump json metadataforall plugins. --playbook-dir BASEDIR Since this tool does not use playbooks, use this as a substitute playbook directory.This sets the relative pathformany features including roles/ group_vars/ etc. --version show program's version number, config file location, configured module search path, module location, executable location and exit -F, --list_files Show plugin names and their source files without summaries (implies --list) -M MODULE_PATH, --module-path MODULE_PATH prepend colon-separated path(s) to module library (def ault=~/.ansible/plugins/modules:/usr/share/ansible/plu gins/modules) -h, --help show this help message and exit -j, --json Change output into json format. -l, --list List available plugins -s, --snippet Show playbook snippet for specified plugin(s) -t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}, --type {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars} Choose which plugin type (defaults to "module"). Available plugin types are : ('become', 'cache', 'callback', 'cliconf', 'connection', 'httpapi', 'inventory', 'lookup', 'netconf', 'shell', 'module', 'strategy', 'vars')-v, --verbose verbose mode(-vvvformore, -vvvv toenableconnection debugging)SeemanpagesforAnsible CLI options or websitefortutorials https://docs.ansible.com

示例:

# 查看模块清单及说明[dyx@controller web]$ ansible-doc -l fortios_router_community_list Configure community li... azure_rm_devtestlab_info Get Azure DevTest Lab... ecs_taskdefinition register a task defini... avi_alertscriptconfig Moduleforsetup of Al... tower_receive Receive assets from An.........# 查看模块清单及位置[dyx@controller web]$ ansible-doc -F fortios_router_community_list /usr/lib/python2.7/site-pac azure_rm_devtestlab_info /usr/lib/python2.7/site-pac ecs_taskdefinition /usr/lib/python2.7/site-pac avi_alertscriptconfig /usr/lib/python2.7/site-pac tower_receive /usr/lib/python2.7/site-pac netapp_e_iscsi_target /usr/lib/python2.7/site-pac azure_rm_acs /usr/lib/python2.7/site-pac......# 查看特定模块说明文档[dyx@controller web]$ ansible-doc user>USER(/usr/lib/python2.7/site-packages/ansible/modules/system/user.py)Manage user accounts and user attributes. For Windows targets, use the[win_user]module instead. * This module is maintained by The Ansible Core Team * This module is maintained by The Ansible Core Team OPTIONS(=is mandatory): - append If`yes',addthe user to thegroupsspecifiedin`groups'. If`no', user will only be added to thegroupsspecifiedin`groups', removing them from all other groups. Mutually exclusive with`local'[Default: False]type: bool# 提示信息NOTES: * There are specific requirements per platform on user management utilities. However they generally come pre- installed with the system and Ansible will require they are present at runtime. If they are not, a descriptive error message will be shown. * On SunOS platforms, the shadowfileis backed up automatically since this module edits it directly. On other platforms, the shadowfileis backed up by the underlying tools used by this module. * On macOS, this module uses`dscl' to create, modify, and delete accounts.`dseditgroup' is used to modify group membership. Accounts are hidden from the login window by modifying`/Library/Preferences/com.apple.loginwindow.plist'.# 作者AUTHOR: Stephen Fromm(@sfromm)# METADATA描述了谁在维护该模块。# status记录了模块开发状态。# stableinterface: 模块的关键字稳定,将尽力确保不删除关键字或更改其含义。# preview: 模块处于技术预览阶段,可能不稳定,其关键字可能会更改,或者它可能需要本身会受到不兼容更改的库或Web服务。# deprecated: 未来某一发行版中将不再提供。# removed: 模块已从发行版中移除,但因文档需要存在存根,以帮助之前的用户迁移到新的模块。METADATA: status: - stableinterface# supported_by记录了哪些社区在维护该模块:# core:Ansible核心开发人员维护,始终随Ansible提供。# curated:模块由社区中的合作伙伴或公司提交并维护。这些模块的维护者必须留意报告的任何问题,或者调取针对该模块提出的请求。在社区维护人员批准了更改后,上游 “core” 开发人员审核对策划模块提出的更改。核心提交者也确保因为Ansible引擎中的变化而对这些模块造成的任何问题得到修正。这些模块目前随Ansible提供,但是可能会在未来某个时候另外打包。# community:模块不受到core上游开发人员、合作伙伴或公司的支持,完全由一般开源社区维护。此类别中的模块仍然完全可用,但对问题的响应速度完全取决于社区。这些模块目前也随Ansible提供,但是可能会在未来某个时候另外打包。supported_by: core# 模块使用示例EXAMPLES: - name: Add the user'johnd'with a specific uid and a primary group of'admin'user: name: johnd comment: John Doe uid:1040group: admin......# 模块返回值说明RETURN VALUES: append: description: Whether or not to append the user togroupsreturned: When state is'present'and the user exists type: bool sample: True comment: description: Comment section frompasswdfile, usually the user name returned: When user exists......

如果现有的模块无法实现现有需求,用户也可以自行编写模块:

  • Ansible会从变量ANSIBLE_LIBRARY中查找模块

  • 如果该变量未设置,将会从ansible.cfg配置文件library设置的位置查找模块

copy模块(文件/目录拷贝)

核心作用:从控制端拷贝文件 / 目录到远程主机,支持权限、属主、内容直接写入等。

案例 1:基础文件拷贝(指定源和目标)

[dyx@controller web]$touch/tmp/local_file.txt[dyx@controller web]$ ansible all -m copy -a"src=/tmp/local_file.txt dest=/opt/remote_file.txt"#验证[root@node1 ~]# ls /opt |grep remoteremote_file.txt
  • 说明:将控制端 /tmp/local_file.txt 拷贝到远程主机 /opt/remote_file.txt ;

  • 备注:目标文件已存在时会覆盖(默认行为)。

案例 2:拷贝并设置权限 + 属主属组

[dyx@controller web]$sudoyuminstall-y httpd[dyx@controller web]$ ansible all -m copy -a"src=/etc/httpd/conf/httpd.conf dest=/tmp/feiyy owner=dyx group=root mode=0644 backup=yes"#验证[root@node1 ~]# ls /tmp|grep feiyyfeiyy
  • 说明:
    • 拷贝 nginx 配置文件到远程 web 服务器;
    • 设置属主 nginx 、属组 nginx ,权限 0644 ;
    • backup=yes :覆盖前自动备份原文件(后缀为时间戳)。

在此拷贝

[root@controller ~]# echo hhh >/etc/httpd/conf/httpd.conf[dyx@controller web]$ ansible all -m copy -a"src=/etc/httpd/conf/httpd.conf dest=/tmp/feiyy owner=dyx group=root mode=0644 backup=yes"#验证[root@node1 ~]# ls /tmp|grep feiyyfeiyy feiyy.6832.2025-12-15@16:42:21~

command模块

command 模块允许管理员在受管节点的命令行中运行任意命令。要运行的命令通过-a选项指定为该模块的参数。

[dyx@controller web]$ ansible node1 -mcommand-a'hostname'node1|CHANGED|rc=0>>node1.dyx.cloud[dyx@controller web]$ ansible node1 -mcommand-a'hostname'-o node1|CHANGED|rc=0|(stdout)node1.dyx.cloud

说明:

  • command 模块执行的远程命令不受受管节点上的shell处理,无法访问shell环境变量,也不能执行重定向和传送等shell操作。

  • 如果临时命令没有指定模块,Ansible默认使用command模块。

shell 模块

shell模块允许您将要执行的命令作为参数传递给该模块。 Ansible随后对受管节点远程执行该命令。与command模块不同的是, 这些命令

将通过受管节点上的shell进行处理。因此,可以访问shell环境变量,也可使用重定向和管道等shell操作。

[dyx@controller web]$ ansible node1 -mcommand-asetnode1|FAILED|rc=2>>[Errno2]No suchfileor directory[dyx@controller web]$ ansible node1 -m shell -asetnode1|CHANGED|rc=0>>BASH=/bin/shBASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepathBASH_ALIASES=()BASH_ARGC=()BASH_ARGV=()BASH_CMDS=()BASH_EXECUTION_STRING=setBASH_LINENO=()BASH_SOURCE=()BASH_VERSINFO=([0]="4"[1]="2"[2]="46"[3]="2"[4]="release"[5]="x86_64-redhat-linux-gnu")BASH_VERSION='4.2.46(2)-release'DIRSTACK=()EUID=0GROUPS=()HOME=/rootHOSTNAME=node1.dyx.cloudHOSTTYPE=x86_64IFS=' 'LANG=en_US.UTF-8LOGNAME=rootLS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:'MACHTYPE=x86_64-redhat-linux-gnuMAIL=/var/mail/dyxOPTERR=1OPTIND=1OSTYPE=linux-gnuPATH=/sbin:/bin:/usr/sbin:/usr/binPOSIXLY_CORRECT=yPPID=2405PS4='+ 'PWD=/home/dyxSHELL=/bin/bashSHELLOPTS=braceexpand:hashall:interactive-comments:posixSHLVL=2SUDO_COMMAND='/bin/sh -c echo BECOME-SUCCESS-msrwdmrluwtjkhtfvqdhffcuglwtfjqc ; /usr/bin/python /home/dyx/.ansible/tmp/ansible-tmp-1765848154.46-2146-236870616870838/AnsiballZ_command.py'SUDO_GID=1001SUDO_UID=1001SUDO_USER=dyxTERM=xtermUID=0USER=rootUSERNAME=rootXDG_SESSION_ID=3_=/usr/bin/python

**注意:**command和shell模块要求被管理主机安装Python。

raw 模块

raw 模块,可以直接在远端主机shell中执行命令,远端主机不需要安装Python(特别是针对网络设备)。在大部分场景中,不推荐使用command、shell、raw模块执行命令,因为这些模块不具有幂等性。

[dyx@controller web]$ ansible node1 -m raw -a'echo "hello world" > /tmp/hello.txt'node1|CHANGED|rc=0>>Shared connection to node1 closed.# 此处多了一个现实:断开连接,相当于通过ssh连接到受管节点执行命令。[dyx@controller web]$ ansible node1 -a'cat /tmp/hello.txt'node1|CHANGED|rc=0>>hello world# 对比shell模块[dyx@controller web]$ ansible node1 -m shell -a'echo "hello ansible " > /tmp/hello.txt'node1|CHANGED|rc=0>>

ansible AD HOC 命令选项

临时命令选项优先级高于配置文件中配置

配置文件指令命令行选项
inventory-i
remote_user-u
ask_pass-k,–ask_pass
become–become,-b
become_method–become_method
become_user–become_user
become_ask_pass–ask-become-pass,-K
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/1/6 21:57:23

Flutter 开发工具链详解

欢迎大家加入开源鸿蒙跨平台开发者社区&#xff0c;一起共建开源鸿蒙跨平台生态。 # Flutter 开发工具链详解 Flutter 是一个由 Google 开发的跨平台移动应用开发框架&#xff0c;其完整的工具链涵盖了从开发环境搭建到应用发布的整个生命周期。以下将详细介绍 Flutter 的核心…

作者头像 李华
网站建设 2025/12/16 23:25:43

Video DownloadHelper 配套应用终极配置指南:告别视频下载烦恼

Video DownloadHelper 配套应用终极配置指南&#xff1a;告别视频下载烦恼 【免费下载链接】vdhcoapp Companion application for Video DownloadHelper browser add-on 项目地址: https://gitcode.com/gh_mirrors/vd/vdhcoapp 还在为浏览器视频下载功能受限而苦恼吗&am…

作者头像 李华
网站建设 2025/12/16 23:25:41

TranslucentTB深度汉化指南:从原理到实战的系统美化艺术

TranslucentTB深度汉化指南&#xff1a;从原理到实战的系统美化艺术 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 对于Windows系统美化…

作者头像 李华
网站建设 2025/12/16 23:24:13

如何快速掌握ComfyUI-Manager:AI绘画插件管理的完整指南

如何快速掌握ComfyUI-Manager&#xff1a;AI绘画插件管理的完整指南 【免费下载链接】ComfyUI-Manager 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Manager 还在为ComfyUI复杂的插件安装流程而烦恼吗&#xff1f;ComfyUI-Manager正是你需要的解决方案&#…

作者头像 李华
网站建设 2025/12/26 16:30:47

如何快速去除视频硬字幕?AI神器video-subtitle-remover完整教程

如何快速去除视频硬字幕&#xff1f;AI神器video-subtitle-remover完整教程 【免费下载链接】video-subtitle-remover 基于AI的图片/视频硬字幕去除、文本水印去除&#xff0c;无损分辨率生成去字幕、去水印后的图片/视频文件。无需申请第三方API&#xff0c;本地实现。AI-base…

作者头像 李华
网站建设 2025/12/16 23:22:10

小红书数据采集终极指南:xhs工具2025完全教程

小红书数据采集终极指南&#xff1a;xhs工具2025完全教程 【免费下载链接】xhs 基于小红书 Web 端进行的请求封装。https://reajason.github.io/xhs/ 项目地址: https://gitcode.com/gh_mirrors/xh/xhs 在内容营销和数据分析的时代&#xff0c;小红书平台已成为品牌洞察…

作者头像 李华