我正在尝试生成一个脚本,该脚本将在带有ssh
的ansible
期望/响应块中复制到远程主机。我想避免写中间文件。
我有两个问题:
- Ansible似乎在
command
中进行了一些处理,这会打乱多行bash
脚本,但我可以用/bin/bash -c 'my multi line command'
(在实际的多行上(绕过它 - 我似乎无法在
bash
调用中正确引用heredoc的EOF标记(见下文(
- name: Generate script on the fly
expect:
command: |
/bin/bash -c 'ssh -o PubkeyAuthentication=no -p {{ ansible_ssh_port }} {{ ansible_user }}@{{ ansible_host }} "cat - > {{ tgtdir }}/myscript.sh" <<-'EOF'
#! /bin/env sh
a="/$0"; a=${a%/*}; a=${a#/}; a=${a:-.}; THIS=$(cd "$a"; pwd)
echo "Script dir == ${THIS}"
echo "{{ someansiblevar }}"
EOF
'
responses:
(.*)password: "{{ ansible_ssh_pass }}"
delegate_to: localhost
(注意,在这个例子中,我显然可以在单引号中使用单引号,但其他变体也都失败了。(
我试图用不同的方式避开第一个EOF
周围的引号,但我总是得到警告:
"stdout_lines": ["/bin/bash: line 10: warning: here-document at line 0 delimited by end-of-file (wanted `EOF')", "", "admin@192.168.1.111's password: "]
并且myscript.sh
的内容要么没有正确地单独保留(即所有$...
都展开(,要么包含最后一个EOF
(因为它没有被识别为分隔符,并且只是读取到命令块的末尾,因此发出警告
正确的处理方法是什么?
(请注意,我委托给localhost
,因为我不想依赖目标主机上的python
,这些是只有ssh
的最小系统(。
将结束EOF向左移动两个空格。目前,它不是从行的开头开始的,所以bash不会将其视为分隔符。
来自bash手册页:
此处文档
这种类型的重定向指示shell从当前源,直到只包含分隔符的行(没有尾部空白(。到那一点为止读取的所有行都是然后用作命令的标准输入。的格式这里的文件是:
<<[-]word here-document delimiter
不执行参数扩展、命令替换、算术扩展或路径名扩展在CCD_ 14上。如果引用了
word
中的任何字符,则delimiter
是word
上的报价删除结果,以及此处文档中的行未展开。如果未引用word
,则此处文档的所有行进行参数扩展、命令替换,以及算术扩展。在后一种情况下,字符序列\<换行符>被忽略,并且\必须用于引用字符\,$和`。如果重定向运算符为<<-
,则所有前导选项卡字符从输入行和包含CCD_ 20。这允许shell脚本中的文档以自然的方式缩进。
因此,您需要从EOF
行中删除缩进,或者使用TAB而不是空格对所有内容进行缩进。我建议前一种选择比较简单。