ansible:lineinfile 几行?
Posted
技术标签:
【中文标题】ansible:lineinfile 几行?【英文标题】:ansible: lineinfile for several lines? 【发布时间】:2014-08-11 14:46:34 【问题描述】:同样的方法有一个模块lineinfile
在文件中添加一行,有没有办法添加多行?
我不想使用模板,因为您必须提供整个文件。 我只是想在现有文件中添加一些东西,而不必知道文件已经包含什么,所以模板不是一个选项。
【问题讨论】:
我知道您不想使用template
,但使用lineinfile
是antipattern。这也是一个强烈的危险信号,即您“不知道文件中有什么”,这会导致出现未知故障的巨大风险。
这不是反模式。 lineinfile 的重点是支持多个源管理同一个文件,这有时是不可避免的。大多数配置文件都有固定的格式,避免冲突的逻辑通常不会太大。
我不知道我电脑上绝大多数文件的内容;并不意味着我想把他们都用核武器炸死!
【参考方案1】:
您可以在loop 中使用lineinfile
built-in。这是一个例子:
- name: Set some kernel parameters
lineinfile:
dest: /etc/sysctl.conf
regexp: " item.regexp "
line: " item.line "
loop:
- regexp: '^kernel.shmall', line: 'kernel.shmall = 2097152'
- regexp: '^kernel.shmmax', line: 'kernel.shmmax = 134217728'
- regexp: '^fs.file-max', line: 'fs.file-max = 65536'
【讨论】:
确保你有 line= 和 regexp= 引号的参数。我没有,我一直收到msg: this module requires key=value arguments
。给出的例子确实是正确的——我只是没有遵循这个例子。
请问第一次更改前如何进行单次备份?也许item.backup? :D
这可能在 Ansible 2.0 之前被投票通过。现在更好的答案是:***.com/a/28306576/972128
@kkurian 当然只有在你插入的时候,而不是在你替换的时候?
@kkurian 如果您使用 blockinfile 解决方案,例如需要在 json 文件中添加一些行并且不需要任何标记。虽然您可以将标记设置为“”,但 ansible blockinfile 仍会查找标记,找不到任何标记,然后再次插入块。因此,没有标记的 blockinfile 不是幂等的,带有循环的 lineinfile 是。【参考方案2】:
您可以尝试改用blockinfile
。
你可以这样做
- blockinfile: |
dest=/etc/network/interfaces backup=yes
content="iface eth0 inet static
address 192.168.0.1
netmask 255.255.255.0"
【讨论】:
blockinfile
模块在我每次选择使用它时都表现出色。我特别喜欢 insertafter
/insertbefore
选项的直观行为。
投票率最高的答案可能是在 Ansible 2.0 之前,但现在这是更正确的答案。
Blockinfile 需要标记。这有时是没有选择的。
我们能用blockinfile
覆盖内容吗?
我认为这是正确的做法。 docs.ansible.com/ansible/blockinfile_module.html【参考方案3】:
这是使用 with_items 解决方案的无噪音版本:
- name: add lines
lineinfile:
dest: fruits.txt
line: ' item '
with_items:
- 'Orange'
- 'Apple'
- 'Banana'
对于每个项目,如果该项目存在于 fruits.txt 中,则不执行任何操作。
如果该项目不存在,它将被附加到文件的末尾。
简单易行。
【讨论】:
这个不能和insertafter结合使用。 如果缺少多行,我希望该项目出现在订单中。如何确定附加项目的顺序?【参考方案4】:如果您需要配置一组唯一的 property=value 行,我建议使用更简洁的循环。例如:
- name: Configure kernel parameters
lineinfile:
dest: /etc/sysctl.conf
regexp: "^ item.property | regex_escape() ="
line: " item.property = item.value "
with_items:
- property: 'kernel.shmall', value: '2097152'
- property: 'kernel.shmmax', value: '134217728'
- property: 'fs.file-max', value: '65536'
使用 Alix Axel 建议的 dict 并添加自动删除匹配的注释掉的条目,
- name: Configure IPV4 Forwarding
lineinfile:
path: /etc/sysctl.conf
regexp: "^#? * item.key | regex_escape() ="
line: " item.key = item.value "
with_dict:
'net.ipv4.ip_forward': 1
【讨论】:
如果使用 with_dict 会更简洁。【参考方案5】:这并不理想,但您可以多次调用lineinfile
。将其与insert_after
一起使用,您可以获得所需的结果:
- name: Set first line at EOF (1/3)
lineinfile: dest=/path/to/file regexp="^string 1" line="string 1"
- name: Set second line after first (2/3)
lineinfile: dest=/path/to/file regexp="^string 2" line="string 2" insertafter="^string 1"
- name: Set third line after second (3/3)
lineinfile: dest=/path/to/file regexp="^string 3" line="string 3" insertafter="^string 2"
【讨论】:
是的,但它仍然是一次一行。如果我有 15 行,我宁愿只用一个命令来添加它们。这似乎是不可能的。 谢谢。似乎这仍然是在之后/之前插入多行的唯一方法。【参考方案6】:我可以通过在 line 参数中使用 \n
来做到这一点。
如果可以验证文件,则特别有用,并且添加单行会生成无效文件。
就我而言,我使用以下命令将AuthorizedKeysCommand
和AuthorizedKeysCommandUser
添加到sshd_config:
- lineinfile: dest=/etc/ssh/sshd_config line='AuthorizedKeysCommand /etc/ssh/ldap-keys\nAuthorizedKeysCommandUser nobody' validate='/usr/sbin/sshd -T -f %s'
仅添加其中一个选项会生成验证失败的文件。
【讨论】:
这将在每次运行 playbook 时创建一个额外的行——它不能正确识别该行已经存在。至少,我在 Ansible 1.7.1 上就是这种情况 我报告了 bug,但 Ansible 人员没有兴趣修复它。 现在有一个新的 blockinfile 模块应该比那个解决方案更好。 (docs.ansible.com/ansible/blockinfile_module.html)【参考方案7】:要添加多行,您可以使用块文件:
- name: Add mappings to /etc/hosts
blockinfile:
path: /etc/hosts
block: |
'10.10.10.10 server.example.com'
'10.10.10.11 server1.example.com'
要添加一行,您可以使用 lininfile:
- name: server.example.com in /etc/hosts
lineinfile:
path: /etc/hosts
line: '192.0.2.42 server.example.com server'
state: present
【讨论】:
【参考方案8】:要添加多行,您可以使用 lineinfile
模块和 with_items
还包括变量 vars
以使其简单:)
---
- hosts: localhost #change Host group as par inventory
gather_facts: no
become: yes
vars:
test_server: "10.168.1.1"
test_server_name: "test-server"
file_dest: "/etc/test/test_agentd.conf"
- name: configuring test.conf
lineinfile:
dest: " item.dest "
regexp: " item.regexp "
line: " item.line "
with_items:
- dest: '" file_dest "', regexp: 'Server=', line: 'Server="test_server"'
- dest: '" file_dest "', regexp: 'ServerActive=', line: 'ServerActive="test_server"'
- dest: '" file_dest "', regexp: 'Hostname=', line: 'Hostname="test_server_name"'
【讨论】:
【参考方案9】:要在配置文件中添加多行,您可以使用" "
而不是' '
和转义序列\n
用于lineinfile
ansible 模块中的新行:
- name: Configure core-site.xml
lineinfile:
path: /etc/hadoop/core-site.xml
insertafter: '^<configuration>'
line: "Line 1 \n Line 2 \n Line 3"
【讨论】:
以上是关于ansible:lineinfile 几行?的主要内容,如果未能解决你的问题,请参考以下文章