[root@zhyq-yunwei-test /srv/ceshi-ansible/m-park]# cat jx_all_script.yml --- - name: 执行远程机器上的脚本 hosts: m_park_all tasks: - name: 切换到脚本所在目录并执行 ansible.builtin.shell: | cd /root/jx/ ./46c221be-6ab2-ef53-1589-fe16877914f4.sh null args: chdir: /root/jx/ [root@zhyq-yunwei-test /srv/ceshi-ansible/m-park]# cat hosts [m_park_frontend] 10.104.3.146 ansible_ssh_user=zhyq ansible_become_pass=Always_88jk ansible_become_user=root 10.104.3.155 ansible_ssh_user=zhyq ansible_become_pass=Always_88jk ansible_become_user=root TASK [切换到脚本所在目录并执行] ***************************************************************************************************************************** fatal: [10.104.3.155]: FAILED! => {"changed": false, "msg": "Unable to change directory before execution: [Errno 13] Permission denied: b'/root/jx'"} fatal: [10.104.3.146]: FAILED! => {"changed": false, "msg": "Unable to change directory before execution: [Errno 13] Permission denied: b'/root/jx'"}分析一下原因?
时间: 2025-04-09 08:55:22 浏览: 28
<think>好的,我现在需要分析用户提供的Ansible执行错误。首先看看错误信息:“Permission denied: b'/root/jx'”,这说明Ansible任务在切换目录时遇到了权限问题。用户的任务是切换到/root/jx并执行脚本,但两个主机都失败了。
首先,检查Ansible的hosts文件。用户使用zhyq用户通过ansible_ssh_user连接,并设置了ansible_become_user为root,密码也提供了。这说明Ansible会尝试通过sudo切换到root用户执行任务。但问题可能出在权限提升的过程中。
任务中使用了shell模块,并且指定了chdir参数为/root/jx。由于/root目录默认只有root用户有权限访问,所以即使使用become,可能因为某些原因导致切换目录失败。可能的因素包括:sudo权限配置问题,目标目录不存在,或者zhyq用户无法通过sudo获得足够的权限访问/root/jx。
另外,检查任务中的命令部分。用户用了shell模块,并尝试在命令中cd到目录,同时又在args中指定了chdir,这可能有重复。不过Ansible会优先使用chdir参数,所以可能需要确认是否正确使用。
可能的原因包括:1. zhyq用户没有通过sudo切换到root的权限,或者sudo时需要密码但未正确配置;2. /root/jx目录不存在;3. 目录权限设置不正确,即使作为root也无法访问;4. Ansible任务中的become配置缺失或错误。
需要建议用户检查目录是否存在,确认zhyq用户的sudo权限,是否需要在playbook中显式启用become,以及检查目标目录的权限是否正确。此外,建议简化任务,直接使用chdir参数而不要在shell命令中cd,以避免潜在问题。</think>您遇到的 **Permission denied** 错误是由于 Ansible 执行任务时缺乏对 `/root/jx` 目录的访问权限。以下是详细分析和解决方案:
---
### **错误原因分析**
#### 1. **权限上下文问题**
- 从 `hosts` 文件可见:您通过 `zhyq` 用户连接远程主机,并使用 `ansible_become_user=root` 提权到 root 用户。
- **但 `/root` 目录默认权限是 `700`(仅允许 root 用户访问),即使通过 `sudo` 提权,Ansible 在执行 `chdir` 参数时可能仍以 `zhyq` 用户身份尝试切换目录,导致权限拒绝**。
#### 2. **双重路径切换冲突**
- 任务中同时使用了 `shell` 模块的 `cd` 命令和 `args.chdir` 参数,这会导致路径切换逻辑混乱:
```yaml
shell: |
cd /root/jx/ # 在 shell 中切换目录
./46c221be-6ab2-ef53-1589-fe16877914f4.sh null
args:
chdir: /root/jx/ # Ansible 先尝试切换目录
```
#### 3. **潜在目录不存在**
- 如果远程主机的 `/root/jx` 目录不存在,也会触发此错误。
---
### **解决方案**
#### 1. **显式声明提权操作**
在 Playbook 中明确启用 `become`(提权)并指定提权用户:
```yaml
- name: 执行远程机器上的脚本
hosts: m_park_all
become: yes # 启用提权
become_user: root # 提权到 root 用户
tasks:
- name: 执行脚本
ansible.builtin.shell:
cmd: ./46c221be-6ab2-ef53-1589-fe16877914f4.sh null
chdir: /root/jx # 直接指定工作目录
```
#### 2. **简化路径切换逻辑**
删除冗余的 `cd` 命令,仅通过 `chdir` 参数控制工作目录:
```yaml
shell: ./46c221be-6ab2-ef53-1589-fe16877914f4.sh null # 直接执行脚本
args:
chdir: /root/jx
```
#### 3. **验证目录存在性和权限**
- 确保远程主机的 `/root/jx` 目录存在且权限正确:
```bash
# 手动检查目录是否存在
ansible m_park_all -m stat -a "path=/root/jx"
# 若不存在则创建目录
ansible m_park_all -m file -a "path=/root/jx state=directory owner=root group=root mode=0755" --become
```
#### 4. **检查 sudo 配置**
确认 `zhyq` 用户是否被允许通过 `sudo` 提权到 root(检查 `/etc/sudoers` 文件):
```bash
# 在远程主机上执行
visudo
# 确保包含如下配置
zhyq ALL=(ALL) NOPASSWD: ALL
```
---
### **完整修复后的 Playbook 示例**
```yaml
---
- name: 执行远程机器上的脚本
hosts: m_park_all
become: yes
become_user: root
tasks:
- name: 执行脚本
ansible.builtin.shell:
cmd: ./46c221be-6ab2-ef53-1589-fe16877914f4.sh null
chdir: /root/jx
```
---
### **验证操作**
执行 Playbook 并观察输出:
```bash
ansible-playbook jx_all_script.yml -i hosts
```
若仍有错误,可添加 `-vvv` 参数查看详细调试日志:
```bash
ansible-playbook jx_all_script.yml -i hosts -vvv
```
阅读全文
相关推荐









