【发布时间】:2020-01-07 00:55:44
【问题描述】:
我有希望在目标节点上运行的 check.sh 脚本:
cat check.sh
str=`echo $1 | sed -e 's#[\][\]n# #g'`
echo $str>check.row
假设用参数中的单个空格替换 \n 并将其保存在 check.row 文件中。
当我在目标服务器上手动运行它时,我得到了如下所示的良好输出结果:
bash -x ./check.sh '/fin/app/01/scripts\\n/fin/app/01/sql'
++ echo '/fin/app/01/scripts\\n/fin/app/01/sql'
++ sed -e 's#[\][\]n# #g'
+ str='/fin/app/01/scripts /fin/app/01/sql'
+ echo /fin/app/01/scripts /fin/app/01/sql
生成的check.row如下所示:
[user1@remotehost1 ~]$ cat check.row
/fin/app/01/scripts /fin/app/01/sql
但是,当我使用 ansible shell 或命令模块运行相同的命令时,我没有得到预期的结果。
下面是我的剧本:
tasks:
- copy:
src: "{{ playbook_dir }}/files/check.sh"
dest: "~/"
mode: 0754
- set_fact:
install_dir: "{{ hostvars[\'localhost\'][\'command_result\'].stdout.split('\t')[2] }}"
- shell: "bash -x ~/check.sh '{{ install_dir }}' > ~/check_rollback.log"
查看 ansible 的调试输出如下:
changed: [10.8.44.55] => {
"changed": true,
"cmd": "bash -x ~/check.sh '/fin/app/01/scripts\\n/fin/app/01/sql' > ~/check_rollback.log",
"delta": "0:00:00.118943",
"end": "2019-09-04 10:50:16.503745",
"invocation": {
"module_args": {
"_raw_params": "bash -x ~/check.sh '/fin/app/01/scripts\\n/fin/app/01/sql' > ~/check_rollback.log",
"_uses_shell": true,
"argv": null,
"chdir": null,
"creates": null,
"executable": null,
"removes": null,
"stdin": null,
"stdin_add_newline": true,
"strip_empty_ends": true,
"warn": true
}
},
"rc": 0,
"start": "2019-09-04 10:50:16.384802",
"stderr": "++ echo '/fin/app/01/scripts\\n/fin/app/01/sql'\n++ sed -e 's#[\\][\\]n# #g'\n+ str='/fin/app/01/scripts\\n/fin/app/01/sql'\n+ echo '/fin/app/01/scripts\\n/fin/app/01/sql'",
"stderr_lines": [
"++ echo '/fin/app/01/scripts\\n/fin/app/01/sql'",
"++ sed -e 's#[\\][\\]n# #g'",
"+ str='/fin/app/01/scripts\\n/fin/app/01/sql'",
"+ echo '/fin/app/01/scripts\\n/fin/app/01/sql'"
],
"stdout": "",
"stdout_lines": [] }
这里是 ansible 运行的 check.row 文件输出:
[user1@remotehost1 ~]$ cat check.row
/fin/app/01/scripts\\n/fin/app/01/sql
现在打印的是 \n,而不是单个空格。
我正在使用最新版本的 ansible。
可以轻松复制此问题。您能否建议我为什么会遇到此问题以及如何解决此问题?
【问题讨论】:
-
将
hexdump -C <<<"$1" >>check.row添加到您的脚本中,看看$1的真正内容。记得引用你的论点,不是echo $1,而是echo "$1"etc。 -
@Ashar,你的问题解决了吗?
-
我需要在周末测试一下。问题可能是使用 printf vs echo。肯定有很多解决方案可以替换字符串并在 shell 脚本上完成这项工作,但是当通过 Ansible 调用时同样失败。可能是一个全新的帖子,我会在其中介绍所有案例。