ansible : 여러 줄의 lineinfile?


162

lineinfile파일에 한 줄을 추가 하는 모듈이있는 것과 같은 방법으로 여러 줄을 추가하는 방법이 있습니까?

전체 파일을 제공해야하기 때문에 템플릿을 사용하고 싶지 않습니다. 템플릿이 옵션이 아니므로 파일에 이미 무엇이 포함되어 있는지 모른 채 기존 파일에 무언가를 추가하고 싶습니다.


나는 당신이 사용하고 싶지 않다는 것을 이해 template하지만 사용 lineinfile하는 것은 안티 패턴 입니다. 또한 "파일의 내용을 모릅니다"라는 강력한 위험 신호로 알 수없는 오류가 발생할 위험이 있습니다.
tedder42

39
안티 패턴이 아닙니다. lineinfile의 요점은 동일한 파일을 관리하는 여러 소스를 지원하는 것이며 때로는 피할 수없는 경우도 있습니다. 대부분의 구성 파일은 형식이 고정되어 있으며 충돌을 피하기위한 논리는 일반적으로 그리 크지 않습니다.
Doug F

내 PC에있는 대부분의 파일에 무엇이 있는지 모르겠습니다. 내가 모두 핵무기를 원한다는 의미는 아닙니다!
DylanYoung

답변:


222

루프 를 사용 하여 수행 할 수 있습니다. 다음은 with_items루프 를 사용하는 예입니다 .

- name: Set some kernel parameters
  lineinfile:
    dest: /etc/sysctl.conf
    regexp: "{{ item.regexp }}"
    line: "{{ item.line }}"
  with_items:
    - { 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. 주어진 예제에는 이것이 정확합니다. 나는 예제를 따르지 않았습니다.
JDS

1
첫 번째 변경 전에 단일 백업을 수행하는 방법을 물어볼 수 있습니까? 아마도 item.backup? : D
tdihp

6
이것은 아마도 Ansible 2.0 이전에 투표되었을 것입니다. 더 좋은 대답은 다음과 같습니다. stackoverflow.com/a/28306576/972128
kkurian

@kkurian 확실히 삽입하는 경우에만, 교체하는 경우에는 안됩니까?
ndtreviv 2016 년

7
@kkurian json 파일에 일부 줄을 추가하고 마커를 원하지 않으면 blockinfile 솔루션이 작동하지 않습니다. 마커를 ""로 설정할 수는 있지만, 사용 가능한 블록 파일은 여전히 ​​마커를 찾고 아무것도 찾지 못하고 블록을 다시 삽입합니다. 따라서 마커가없는 blockinfile은 dem 등성이 아니며 루프가있는 lineinfile은 없습니다.
터무니없는

176

blockinfile대신 사용할 수 있습니다 .

당신은 같은 것을 할 수 있습니다

- blockinfile: |
    dest=/etc/network/interfaces backup=yes
    content="iface eth0 inet static
        address 192.168.0.1
        netmask 255.255.255.0"

8
blockinfile모듈은 멋지고 내가 그것을 사용하기로 선택한 모든 시간을 일했다. 나는 특히 insertafter/ insertbefore옵션 의 직관적 인 행동을 좋아합니다 .
Jay Taylor

9
가장 투표가 많은 답변은 아마도 Ansible 2.0 이전이었을 것입니다. 그러나 이것은 지금보다 정확한 답변입니다.
Willem van Ketwich

11
Blockinfile에는 마커가 필요합니다. 때로는 옵션이 없습니다.
22시 04 분

1
콘텐츠를 덮어 쓸 수 blockinfile있습니까?
pkaramol

1
내가 생각하는 올바른 방법입니다. docs.ansible.com/ansible/blockinfile_module.html
Paulo Victor

20

고유 한 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

2
with_dict를 사용하면 더 간결합니다.
Alix Axel

18

with_items를 사용하는 무소음 버전의 솔루션은 다음과 같습니다.

- name: add lines
  lineinfile: 
    dest: fruits.txt
    line: '{{ item }}'
  with_items:
    - 'Orange'
    - 'Apple'
    - 'Banana' 

fruits.txt에 항목이 있으면 각 항목에 대해 조치가 수행되지 않습니다.

해당 항목이 없으면 파일 끝에 추가됩니다.

쉬워요.


이것은 삽입 후와 함께 사용할 수 없습니다.
22

여러 줄이 없으면 주문에 항목을 표시하고 싶습니다. 항목이 추가 된 순서를 어떻게 확인할 수 있습니까?
MUY Belgium

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"

5
예,하지만 한 번에 한 줄입니다. 15 줄이 있으면 하나의 명령으로 추가하는 것이 좋습니다. 가능하지 않은 것 같습니다.
Michael

1
감사. 이것은 여전히 ​​삽입 후 / 이전에 여러 줄을 수행하는 유일한 방법 인 것 같습니다.
timss

5

\nline 매개 변수를 사용하여 그렇게 할 수있었습니다 .

파일의 유효성을 검사 할 수 있고 한 줄을 추가하면 유효하지 않은 파일이 생성되는 경우 특히 유용합니다.

내 경우, 나는 추가했다 AuthorizedKeysCommandAuthorizedKeysCommandUsersshd_config에서 다음 명령을 :

- lineinfile: dest=/etc/ssh/sshd_config line='AuthorizedKeysCommand /etc/ssh/ldap-keys\nAuthorizedKeysCommandUser nobody' validate='/usr/sbin/sshd -T -f %s'

옵션 중 하나만 추가하면 유효성 검사에 실패한 파일이 생성됩니다.


12
이렇게하면 플레이 북을 실행할 때마다 추가로 줄이 만들어집니다. 줄이 이미 존재한다는 것을 올바르게 인식하지 못합니다. 적어도 Ansible 1.7.1
David

1
나는 버그를 보고 했지만 Ansible 녀석은 그것을 고칠 관심이 없다.
22시 06 분

1
현재 해당 솔루션보다 나은 새로운 blockinfile 모듈이 있습니다. ( docs.ansible.com/ansible/blockinfile_module.html )
Penz

1

여러 줄을 추가하려면 블록 파일을 사용할 수 있습니다.

- 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

1

여러 줄을 추가하려면 변수를 포함하여 lineinfile모듈 을 사용하여 간단하게 만들 수 있습니다. :)with_itemsvars

---
- 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}}"' }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.