bash - Ansible 在期望/命令块中引用 heredoc 在期望命令中找不到分隔符/多行命令
问题描述
我正在尝试生成要在ansible
期望/响应块中复制ssh
到远程主机的脚本。我想避免编写中间文件。
我有两个问题:
- Ansible 似乎做了一些处理,
command
其中弄乱了多行bash
脚本,但我可以解决它/bin/bash -c 'my \ multi \ line \ command'
(在实际多行上) - 我似乎无法在调用中正确引用heredoc的EOF标记(见
bash
下文)
- 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
不对 . 执行参数扩展、命令替换、算术扩展或路径名扩展
word
。如果引用了 in 中的任何字符word
,则delimiter
是删除 on 引号的结果word
,并且 here-document 中的行不展开。如果word
未加引号,则此处文档的所有行都经过参数扩展、命令替换和算术扩展。在后一种情况下,字符序列 \<newline> 被忽略,并且必须使用 \ 来引用字符 \、$ 和 `。如果重定向运算符是<<-
,则从输入行和包含delimiter
. 这允许 shell 脚本中的 here-documents 以自然的方式缩进。
因此,您要么需要从EOF
行中删除缩进,要么使用制表符而不是空格来缩进所有内容。我建议前一种选择更简单。
推荐阅读
- ios - 将参数附加到 NSURLSession 委托方法
- vb.net - System.Windows.Forms.dll 中出现“System.InvalidOperationException”类型的第一次机会异常
- java - doPost() 没有看到参数
- php - 使用 Or-Tools 的车辆路线问题 - 自动决定初始起点
- reactjs - 反应高图表不显示情节线
- javascript - 如何从内部图像onLoad返回变量
- c# - c#:通过电子邮件批准/拒绝:不是按钮:最少点击
- jquery - 卡在带有复选框的jquery中
- c# - MailKit.Net.Imap.ImapProtocolException:“IMAP 服务器问候语中的语法错误。意外的令牌:[atom:OK]”
- java - java - 如何随机生成0到3之间的整数而不使它们在Java中连续?