Ansible 在 expect/command 块中引用了 heredoc 在 expect 命令中找不到定界符/多行命令

Ansible quoted heredoc in expect/command block not finding delimiter / multiline command in expect command

我正在尝试生成一个脚本,以便在 ansible expect/response 块中将 ssh 复制到远程主机。我想避免编写中间文件。

我有两个问题:

  1. Ansible 似乎在 command 中进行了一些处理,这会弄乱多行 bash 脚本,但我可以使用 /bin/bash -c 'my \ multi \ line \ command'(在实际的多行上)
  2. 我似乎无法正确引用 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="/[=11=]"; 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 man-page:

Here Documents

This type of redirection instructs the shell to read input from the current source until a line containing only delimiter (with no trailing blanks) is seen. All of the lines read up to that point are then used as the standard input for a command. The format of here-documents is:

<<[-]word
        here-document 
delimiter 

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word. If any characters in word are quoted, the delimiter is the result of quote removal on word, and the lines in the here-document are not expanded. If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion. In the latter case, the character sequence \<newline> is ignored, and \ must be used to quote the characters \, $, and `. If the redirection operator is <<-, then all leading tab characters are stripped from input lines and the line containing delimiter. This allows here-documents within shell scripts to be indented in a natural fashion.

因此您要么需要从 EOF 行中删除缩进,要么使用制表符而不是空格缩进所有内容。我建议前一个选项更简单。