【问题标题】:How can I copy a multi-line string to a file with literal newlines?如何将多行字符串复制到带有文字换行符的文件中?
【发布时间】:2019-04-05 17:56:28
【问题描述】:

所以我知道我可以这样做:

copy:
  dest: /etc/issue
  content: |
    Hello
    World

但这不起作用:

vars:
  login_banner_text: !!str |-
    "Hello\nWorld"
tasks:
  - name: Set TTY login banner
    copy:
      dest: /etc/issue
      content: "{{ login_banner_text }}"

换行符直接打印到文件中,不进行解析,即它是用\n 字符串填充的单行。我想在不将文件复制到位的情况下执行此操作,因为我需要将此文本复制到两个文件中。

对于一个文件,\n 字符串需要保持未解析,因此它作为单行写入文件。另一方面,我希望解释 \n,以便将文本扩展为多行。

正在使用ini_file 模块修改第一个文件。使用变量声明中的显式\n,此任务按预期工作。

- name: "Set message"
  ini_file:
    dest: /etc/dconf/db/gdm.d/00-security-settings
    section: org/gnome/login-screen
    option: banner-message-text
    value: string '{{ login_banner_text }}'
    create: yes
    tags:
      - always

但是,其他模块也以这种方式运行。

如果我将文件复制到位,则相当长的文本(不是“Hello World”)必须在两个地方维护。

更新

我发现,我认为是一种更好的方法,基于this post。它将横幅存储在一个单独的文件中,然后使用它来修改两个配置文件。所以值只存储在一个地方。但是,@larsks 给出的答案确实回答了最初提出的问题。

- hosts: 127.0.0.1
  connection: local
  vars:
    login_banner_text: "{{ lookup('file', 'login_banner.txt') }}"
  tasks:
    - name: "Set the GNOME3 Login Warning Banner Text"
      ini_file:
        dest: /etc/dconf/db/gdm.d/00-security-settings
        section: org/gnome/login-screen
        option: banner-message-text
        value: '{{ login_banner_text | to_json }}'
        create: yes
      tags:
        - always
    - name: "Set the TTY Login Warning Banner Text"
      copy:
        dest: '/etc/issue'
        content: "{{ '\n' + login_banner_text + '\n' }}"
      tags:
        - always

【问题讨论】:

  • 我不清楚这里的问题是什么:你的第一个例子做了你想要的。你为什么不能那样做呢?
  • 因为它需要存储为带有文字换行符的变量。
  • 您可以使用与第一个示例中 content: 相同的语法来设置变量的值。

标签: ansible newline


【解决方案1】:

您已经知道如何使用文字换行符指定值;在第一个示例中设置 content 键时,您正在这样做。你可以用同样的方式设置变量的值:

---
- hosts: localhost
  gather_facts: false
  vars:
    mytext: |
      Hello
      World
  tasks:
    - copy:
        dest: ./output.txt
        content: "{{ mytext }}"

这将创建带有内容的output.txt

Hello
World

如果您的目标是拥有这样的内容...

[org/gnome/login-screen]

banner-message-text = "Hello\nWorld"

...那么您不需要文字换行符,您需要文字 \n,在这种情况下,这将起作用:

---
- hosts: localhost
  gather_facts: false
  vars:
    mytext: "Hello\\nWorld"

  tasks:
    - ini_file:
        dest: ./example.ini
        section: org/gnome/login-screen
        option: banner-message-text
        value: "{{ mytext }}"
        create: true

这会导致:

[org/gnome/login-screen]
banner-message-text = Hello\nWorld

如果你想引用配置文件中的值,那么:

    - ini_file:
        dest: ./example.ini
        section: org/gnome/login-screen
        option: banner-message-text
        value: '"{{ mytext }}"'
        create: true

这让你:

[org/gnome/login-screen]
banner-message-text = "Hello\nWorld"

你也可以这样做:

---
- hosts: localhost
  gather_facts: false
  vars:
    mytext: |-
      Hello
      World

  tasks:
    - ini_file:
        dest: ./example.ini
        section: org/gnome/login-screen
        option: banner-message-text
        value: '{{ mytext|to_json }}'
        create: true

这会得到与上一个示例相同的输出。

【讨论】:

  • 这不一样。如果我尝试将该变量输出到需要保留换行符的另一个文件,它会将其写为多行。
  • 这就是“文字换行符”的字面意思。这意味着包括实际的换行符,所以你当然会得到多行。这不是你想要做的吗?您能否更新您的问题以明确显示您期望在目标文件中的输出?
  • 字面意思是不被解析或解释。字符串以其原始形式保留。我将更新问题以澄清。
  • 我添加了一些替代方案。
  • 谢谢。输出到普通文本文件时有没有办法解析\n 字符串?使用 YAML 多行运算符是可行的,但在某些地方我需要多个换行符,所以我不想那样做。它使剧本看起来凌乱,并导致编辑器中的语法高亮出现问题。
猜你喜欢
  • 2014-04-18
  • 2011-11-17
  • 2014-12-05
  • 2022-01-21
  • 2018-08-22
  • 1970-01-01
  • 2019-12-12
  • 1970-01-01
相关资源
最近更新 更多