简体   繁体   English

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

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

I'm trying to generate a script to be copied in an ansible expect/response block with ssh to the remote host.我正在尝试使用ssh生成要在ansible expect/response 块中复制到远程主机的脚本。 I'd like to avoid writing intermediate files.我想避免编写中间文件。

I have two issues:我有两个问题:

  1. Ansible seems to do some processing in command which messes up multiline bash scripts, but I can get around it with /bin/bash -c 'my \\ multi \\ line \\ command' (on actual multiple lines) Ansible 似乎在command进行了一些处理,这会弄乱多行bash脚本,但是我可以使用/bin/bash -c 'my \\ multi \\ line \\ command' (在实际的多行上)来解决它
  2. I can't seem to quote the EOF mark for the heredoc correctly within the bash invocation (see below)我似乎无法引用的范围内正确的定界符的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

(Note that in this example I'm apparently getting away with using single quotes within single quotes, but other variations all fail as well.) (请注意,在这个例子中,我显然在单引号内使用单引号,但其他变体也都失败了。)

I have tried to escape the quotes around the first EOF in different ways, but I always get the warning:我试图以不同的方式逃避第一个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: "]

And the contents of myscript.sh are either not correctly left alone (ie all $... expanded), or contain the last EOF (since it is not recognized as delimiter and is just reading to the end of the command block, hence the warning.并且myscript.sh的内容要么没有正确地单独留下(即所有$...展开),要么包含最后一个EOF (因为它不被识别为分隔符并且只是读取到命令块的末尾,因此警告。

What is the correct way of handling this?处理这个问题的正确方法是什么?

(Note that I delegate to localhost because I don't want to rely on python on the target host, these are minimal systems with only ssh ). (请注意,我委托给localhost因为我不想在目标主机上依赖python ,这些是只有ssh最小系统)。

Move the closing EOF left by two spaces.将结束的 EOF 向左移动两个空格。 At the moment it does not start at the beginning of its line, so bash won't see it as a delimiter.目前它不是从其行的开头开始,因此 bash 不会将其视为分隔符。

From the bash man-page:从 bash 手册页:

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.这种类型的重定向指示 shell 从当前源读取输入,直到看到仅包含分隔符(没有尾随空格)的行。 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: here-document 的格式为:

 <<[-]word here-document delimiter

No parameter expansion, command substitution, arithmetic expansion, or pathname expansion is performed on word .不会对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.如果word中的任何字符被引用,则delimiterword上引用删除的结果,并且 here-document 中的行不会被扩展。 If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion.如果word被引用,here-document 的所有行都会进行参数扩展、命令替换和算术扩展。 In the latter case, the character sequence \\<newline> is ignored, and \\ must be used to quote the characters \\, $, and `.在后一种情况下,字符序列 \\<newline> 将被忽略,并且必须使用 \\ 来引用字符 \\、$ 和 `。 If the redirection operator is <<- , then all leading tab characters are stripped from input lines and the line containing delimiter .如果重定向运算符是<<- ,则所有前导制表符都将从输入行和包含delimiter的行中删除。 This allows here-documents within shell scripts to be indented in a natural fashion.这允许 shell 脚本中的 here-document 以自然的方式缩进。

So you'll either need to remove the indentation from the EOF line or indent everything with TABs instead of spaces.因此,您要么需要从EOF行中删除缩进,要么使用制表符而不是空格缩进所有内容。 I suggest that the former option is simpler.我建议前一种选择更简单。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM