可引用的“lineinfile”:添加新行(带有PATH=)或添加到现有行(带有PATH=)

时间:2022-01-26 13:52:41

I am trying to replace or append a path part to the path definition in /etc/environment on a linux box.

我正在尝试在linux机器上替换或附加路径部分到/etc/environment中的路径定义。

Here's what I have:

这就是我有:

//all.yml
my_path: "/usr/bin:/usr/sbin"
my_extra_path: "/usr/extra/path"

In my role-file:

在我role-file:

//updatePath.yml
- name: update /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    backrefs=yes
    regexp='PATH=({{ my_path }}:?)?({{ my_extra_path }}:?)?(.*)'
    line='PATH={{ my_extra_path }}:{{ my_extra_path }}:\3'

Now when I run the role, it works fine updating an existing PATH-line, but not creating duplicates within the line or even duplicate lines. So far so good.

现在,当我运行这个角色时,它可以很好地更新现有的路径,但是不会在行中创建重复,甚至不会创建重复的行。目前为止一切都很顺利。

When there is no line with "PATH=" present, I would expect it to add a new one. But it doesn't.

当没有“PATH=”present的行时,我希望它添加一个新的。但它不是。

Is my expectation wrong or where lies the problem?

我的期望是错的还是问题所在?

2 个解决方案

#1


2  

You are using the backrefs: true flag, which prevents lineinfile from changing the file if the line does not already exist. From the docs:

您正在使用backrefs: true标志,如果行不存在,它可以防止lineinfile更改文件。从文档:

Used with state=present. If set, line can contain backreferences (both positional and named) that will get populated if the regexp matches. This flag changes the operation of the module slightly; insertbefore and insertafter will be ignored, and if the regexp doesn't match anywhere in the file, the file will be left unchanged. If the regexp does match, the last matching line will be replaced by the expanded line parameter.

使用状态=。如果设置,line可以包含反向引用(位置引用和命名引用),如果regexp匹配,这些引用将被填充。这个标志稍微改变了模块的操作;将忽略insertbefore和insertafter,如果regexp不匹配文件中的任何地方,文件将保持不变。如果regexp确实匹配,则最后匹配的行将被扩展的行参数替换。

Since you need to create the line if it does not exist, you should use:

因为如果线不存在,你需要创建它,你应该使用:

- name: Check whether /etc/environment contains PATH
  command: grep -Fxq "PATH=" /etc/environment
  register: checkpath
  ignore_errors: True
  changed_when: False

//updatePath.yml
- name: Add path to /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    regexp='^PATH='
    line='PATH={{ my_extra_path }}'
  when: not checkpath.rc == 0

- name: update /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    backrefs=yes
    regexp='PATH=({{ my_path }}:?)?({{ my_extra_path }}:?)?(.*)'
    line='PATH={{ my_extra_path }}:{{ my_extra_path }}:\3'
  when: checkpath.rc == 0

#2


0  

Same idea as here : https://*.com/a/40890850/7231194 or here : https://*.com/a/40891927/7231194

这里也有同样的想法:https://*.com/a/40890850/7231194或者这里:https://*.com/a/40891927/7231194

Steps are:

步骤是:

  • Try to replace the line.
  • 试着换一条线。
  • If replace mod change it. Cool, it's over !
  • 如果替换mod,就改变它。冷静,一切都结束了!
  • If replace mod doesn't change, add the line
  • 如果替换mod不变,添加行

Example

例子

# Vars
- name: Set parameters
  set_fact:
    my_path: "/usr/bin:/usr/sbin"
    my_extra_path: "/usr/extra/path"

# Tasks
- name: Try to replace the line if it exists
  replace:
    dest    : /dir/file
    replace : 'PATH={{ my_extra_path }}'
    regexp  : '^PATH=.*'
    backup  : yes
  register  : tryToReplace

# If the line not is here, I add it
- name: Add line
  lineinfile:
    state   : present
    dest    : /dir/file
    line    : '{{ my_extra_path }}'
    regexp  : ''
    insertafter: EOF
  when: tryToReplace.changed == false

#1


2  

You are using the backrefs: true flag, which prevents lineinfile from changing the file if the line does not already exist. From the docs:

您正在使用backrefs: true标志,如果行不存在,它可以防止lineinfile更改文件。从文档:

Used with state=present. If set, line can contain backreferences (both positional and named) that will get populated if the regexp matches. This flag changes the operation of the module slightly; insertbefore and insertafter will be ignored, and if the regexp doesn't match anywhere in the file, the file will be left unchanged. If the regexp does match, the last matching line will be replaced by the expanded line parameter.

使用状态=。如果设置,line可以包含反向引用(位置引用和命名引用),如果regexp匹配,这些引用将被填充。这个标志稍微改变了模块的操作;将忽略insertbefore和insertafter,如果regexp不匹配文件中的任何地方,文件将保持不变。如果regexp确实匹配,则最后匹配的行将被扩展的行参数替换。

Since you need to create the line if it does not exist, you should use:

因为如果线不存在,你需要创建它,你应该使用:

- name: Check whether /etc/environment contains PATH
  command: grep -Fxq "PATH=" /etc/environment
  register: checkpath
  ignore_errors: True
  changed_when: False

//updatePath.yml
- name: Add path to /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    regexp='^PATH='
    line='PATH={{ my_extra_path }}'
  when: not checkpath.rc == 0

- name: update /etc/environment
  lineinfile:
    dest=/etc/environment
    state=present
    backrefs=yes
    regexp='PATH=({{ my_path }}:?)?({{ my_extra_path }}:?)?(.*)'
    line='PATH={{ my_extra_path }}:{{ my_extra_path }}:\3'
  when: checkpath.rc == 0

#2


0  

Same idea as here : https://*.com/a/40890850/7231194 or here : https://*.com/a/40891927/7231194

这里也有同样的想法:https://*.com/a/40890850/7231194或者这里:https://*.com/a/40891927/7231194

Steps are:

步骤是:

  • Try to replace the line.
  • 试着换一条线。
  • If replace mod change it. Cool, it's over !
  • 如果替换mod,就改变它。冷静,一切都结束了!
  • If replace mod doesn't change, add the line
  • 如果替换mod不变,添加行

Example

例子

# Vars
- name: Set parameters
  set_fact:
    my_path: "/usr/bin:/usr/sbin"
    my_extra_path: "/usr/extra/path"

# Tasks
- name: Try to replace the line if it exists
  replace:
    dest    : /dir/file
    replace : 'PATH={{ my_extra_path }}'
    regexp  : '^PATH=.*'
    backup  : yes
  register  : tryToReplace

# If the line not is here, I add it
- name: Add line
  lineinfile:
    state   : present
    dest    : /dir/file
    line    : '{{ my_extra_path }}'
    regexp  : ''
    insertafter: EOF
  when: tryToReplace.changed == false