我有一个任务,我想在远程服务器的 shell 上运行以下命令,但是每当我运行我的剧本时,它总是给我异常:
- name: copy files
shell: "machines=(machineA machineB machineC); for machine in $(shuf -e ${machines[@]}); do ssh -o StrictHostKeyChecking=no david@$machine 'ls -1 /process/snap/{{ folder }}/*' | parallel -j{{ threads }} 'scp -o StrictHostKeyChecking=no david@${machine}:{} /data/files/'; [ $? -eq 0 ] && break; done"
以下是错误:我不明白我在这里做错了什么?
"stderr": "/bin/sh: 1: Syntax error: \"(\" unexpected", "stderr_lines": ["/bin/sh: 1: Syntax error: \"(\" unexpected"], "stdout": "", "stdout_lines": []}
我可以在任何远程服务器的 shell 上直接运行此命令,但在通过 ansible 运行时遇到问题。
这是我将其转换为一行并在 shell 模块中使用的脚本:
machines=(machineA machineB machineC)
for machine in $(shuf -e ${machines[@]}); do
ssh -o StrictHostKeyChecking=no david@$machine 'ls -1 /process/snap/{{ folder }}/*' | parallel -j{{ threads }} 'scp -o StrictHostKeyChecking=no david@${machine}:{} /data/files/'
[ $? -eq 0 ] && break
done
更新:
我现在尝试这样做,但它给出了不同的异常。
- name: copy files
shell: |
set -x
machines=(machineA machineB machineC)
for machine in $(shuf -e ${machines[@]}); do
ssh -o StrictHostKeyChecking=no david@$machine 'ls -1 /process/snap/{{ folder }}/*' | parallel -j{{ parallelism }} 'scp -o StrictHostKeyChecking=no david@${machine}:{} /data/files/'
[ $? -eq 0 ] && break
done
args:
executable: /bin/bash
完整错误:(我已将其缩短)
致命:[some_machine]:失败! => {“changed”: true, “cmd”: “machines=(machineA machineB machineC)\n for machine in $(shuf -e ${machines[@]}); do\n ssh -o StrictHostKeyChecking=no david@$machine 'ls -1 /process/snap/20180422/*' | parallel -j10 'scp -o StrictHostKeyChecking=no david@${machine}:{} /data/files/'\n [ $? -eq 0 ] && break\n done", “delta”: “0:00:37.546329", “end”: “2018-04-29 23:27:44.003538", “msg”: “非零返回码", “rc”: 1, “start”: “2018-04-29 23:27:06.457209", “stderr”: “ssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知已知\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务\r\nssh:无法解析主机名:未知的名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh: 无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知\r\nssh:无法解析主机名:名称或服务未知known\r\nssh:无法解析主机名:名称或服务未知”、“ssh:无法解析主机名:名称或服务未知”、“ssh:无法解析主机名:名称或服务未知”],“stdout”:“”,“stdout_lines”:[]}
我也尝试了这个基本方法,并且没有任何错误,所以我认为它有效?
- name: copy files
shell: |
set -x
machines=(machineA machineB machineC)
for machine in $(shuf -e ${machines[@]}); do
echo $machine
[ $? -eq 0 ] && break
done
args:
executable: /bin/bash
我认为我的 scp 语句可能存在问题?我不确定,只是猜测?
答案1
好吧,我无法说出您的问题到底是什么,但错误表明您的命令中存在语法错误。这几乎肯定与执行时转义或未正确翻译的内容有关。
我必须提出几件事。首先,使用 yaml 语法来包含包含行尾的文本块。
- name: Run Script
shell: |
machines=(machineA machineB machineC)
for machine in $(shuf -e ${machines[@]}); do
ssh -o StrictHostKeyChecking=no david@$machine 'ls -1 /process/snap/{{ folder }}/*' |
parallel -j{{ threads }} 'scp -o StrictHostKeyChecking=no david@${machine}:{} /data/files/'
[ $? -eq 0 ] && break
done
我认为你的片段可能有一些巴什主义。您可能需要指定脚本通过以下方式执行狂欢代替/bin/sh
。
- name: Run command that requires bash
shell: echo 'not a very good example.
args:
executable: /bin/bash
您可能还想添加一个set -x
作为片段的第一行。shell 的更详细输出应该可以帮助您了解错误到底是什么。
当然,我也建议你尝试使用 Ansible 模块来执行此操作。我怀疑也许将同步模块与异步功能。
答案2
这对我有用:
- name: Generate new certificate
shell: "keytool -genkey -keystore {{ keystore_key }}
-storepass {{ keystore_pass }} \
-storetype {{ keystore_type }} \
-alias {{ keystore_alias }} \
-validity {{ keystore_validity }} \
-keysize {{ keystore_keysize }} \
-keyalg {{ keystore_keyalg }}"
答案3
既然您说您可以在任何远程服务器的 shell 上直接运行此命令,请尝试使用 Ansible 的脚本模块。
- name: Run a script with arguments
script: /some/local/script.sh --some-argument 1234
文档在这里:https://docs.ansible.com/ansible/latest/modules/script_module.html
干杯