Ansible Playbook在Jenkins执行失败但CLI正常的解决方法
解决Jenkins中执行带通配符的Ansible Playbook Shell命令失败问题
问题背景
- 需求:获取指定目录中匹配
*006*模式的文件 - 问题:编写的Ansible Playbook在本地命令行执行正常,但在Jenkins 2.319.2环境中执行失败
- 疑问:如何修复该执行失败问题?
原Playbook代码
- name: A Playbook to build artifacts hosts: targetservers vars: path_to_files: /opt/app/jenkins/sandbox_project_12345 debugger: never become: yes become_user: root gather_facts: no remote_user: test_user ignore_errors: no tasks: - name: ping all ping: - name: List of files to be copied shell: bash -c 'ls {{ path_to_files + "/*006*" }}' delegate_to: localhost register: files_to_be_copied - name: Loop through files debug: msg="{{ "Item = " + item }}" with_items: "{{ files_to_be_copied.stdout_lines }}"
执行错误信息
TASK [List of files to be copied] ********************************************** fatal: [server.company_name.com -> localhost]: FAILED! => {"changed": true, "cmd": "bash -c 'ls /opt/app/jenkins/sandbox_project_12345/2212.00*006*'", "delta": "0:00:00.010146", "end": "2022-10-25 14:34:54.516178", "msg": "non-zero return code", "rc": 2, "start": "2022-10-25 14:34:54.506032", "stderr": "ls: cannot access /opt/app/jenkins/sandbox_project_12345/2212.00*006*: No such file or directory", "stderr_lines": ["ls: cannot access /opt/app/jenkins/sandbox_project_12345/2212.00*006*: No such file or directory"], "stdout": "", "stdout_lines": []}
问题原因
本地命令行执行时,shell会自动展开通配符*,将其替换为匹配的文件名;但在Jenkins环境中,bash -c后的单引号会阻止通配符展开,导致ls直接尝试查找包含*字符的文件,自然找不到对应路径。此外,Jenkins执行用户可能与本地用户权限不同,导致目录访问受限。
解决方法
方案1:使用Ansible内置find模块(推荐)
Ansible的find模块专门用于查找文件,无需依赖shell通配符展开,兼容性更强:
- name: List of files to be copied find: paths: "{{ path_to_files }}" patterns: "*006*" delegate_to: localhost register: files_to_be_copied - name: Loop through files debug: msg="Item = {{ item.path }}" loop: "{{ files_to_be_copied.files }}"
该模块会直接返回匹配的文件对象,通过item.path可获取完整文件路径。
方案2:调整Shell命令写法
修改shell任务,避免单引号阻止通配符展开:
- name: List of files to be copied shell: ls {{ path_to_files }}/*006* delegate_to: localhost register: files_to_be_copied args: warn: false # 关闭ls命令的安全警告(可选)
或者如果必须使用bash -c,改用双引号包裹命令:
shell: bash -c "ls {{ path_to_files }}/*006*"
双引号不会阻止shell展开通配符和变量,确保ls能正确匹配文件。
方案3:检查Jenkins用户权限
确认Jenkins执行用户(通常为jenkins用户)对目标目录/opt/app/jenkins/sandbox_project_12345有读权限,可通过以下命令验证:
sudo -u jenkins ls /opt/app/jenkins/sandbox_project_12345/*006*
如果权限不足,需调整目录或文件的权限,或让Jenkins以有权限的用户执行Playbook。
内容的提问来源于stack exchange,提问作者ChicagoSteve
相关产品推荐
相关产品推荐

