我正在修改/boot/cmdline.txt以将容器功能添加到Raspberry Pi,所以我需要在同一行中将cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
添加到文件中。
我正在尝试使用lineinfile
模块来完成此尝试,
- hosts: mypi
become: yes
tasks:
- name: Enable container features
lineinfile:
path: /boot/cmdline.txt
regex: " cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory"
line: " cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory"
insertafter: EOF
state: present
我一直在尝试将insertafter
修改为BOF,也使用insertbefore
,使用正则表达式来匹配最后一个单词……但是最终却增加了回车符。我一直无法找到不添加新行的方法。
答案 0 :(得分:2)
由于文件中只有一行,因此可以使用replace
或lineinfile
来完成。这是replace
版本:
- name: Enable container features
replace:
path: cmdline.txt
regexp: '^([\w](?!.*\b{{ item }}\b).*)$'
replace: '\1 {{ item }}'
with_items:
- "cgroup_enable=cpuset"
- "cgroup_memory=1"
- "cgroup_enable=memory"
从here
那里窃取了答案答案 1 :(得分:2)
正如 Vladimir 指出的那样,不幸的是,Jack 的回答对于空文件是不够的,如果所需的参数已经存在于行的开头,那么它也会失败。 以下建议的解决方案应解决这些问题。特别是,它应该
# cmdline.yml
- name: read cmdline.txt
become: true
slurp: "src={{ cmdline_txt_path }}"
register: result_cmdline
- name: generate regular expression for existing arguments
set_fact:
regex_existing: '{{ "\b" + key|string + "=" + ("[\w]*" if update else value|string) + "\b" }}'
key_value_pair: '{{ key|string + "=" + value|string }}'
- name: generate regular expression for new arguments
set_fact:
regex_add_missing: '{{ "^((?!(?:.|\n)*" + regex_existing + ")((?:.|\n)*))$" }}'
- name: update cmdline.txt
become: true
copy:
content: '{{ result_cmdline.content
| b64decode
| regex_replace(regex_existing, key_value_pair)
| regex_replace(regex_add_missing, key_value_pair + " \1")
}}'
dest: "{{ cmdline_txt_path }}"
用法:
- set_fact:
cmdline_txt_path: /boot/cmdline.txt
- include_tasks: cmdline.yml
vars:
key: cgroup_enable
value: memory
update: false
# will add the argument if the key-value-pair doesn't exist
- include_tasks: cmdline.yml
vars:
key: cgroup_enable
value: cpu
update: false
- include_tasks: cmdline.yml
vars:
key: cgroup_memory
value: 1
update: true
# will replace the value of the first matching key, if found;
# will add it if it's not found
但是,我可能遗漏了一些边缘情况 - 如果您发现任何问题,请告诉我。
答案 2 :(得分:1)
Q:“ Ansible lineinfile模块:不添加新行。找到不添加新行的方法。”
A:不可能。新行将始终由模块lineinfile
添加。例如,请参见source
b_lines.insert(index[1], b_line + b_linesep)
这是添加新行的方式。此类添加将以b_linesep
终止。查看变量如何为defined
b_linesep = to_bytes(os.linesep, errors='surrogate_or_strict')
当您要遍历文本文件的各行时使用os.linesep。内部扫描器可以识别os.linesep并将其替换为单个“ \ n”。
replace
的任务也无法解决此问题。它既不创建没有换行的行,也不以这种方式修改现有行。除此之外,它不是幂等的。
- name: Enable container features
replace:
path: cmdline.txt
regexp: '^([\w](?!.*\b{{ item }}\b).*)$'
replace: '\1 {{ item }}'
loop:
- "cgroup_enable=cpuset"
- "cgroup_memory=1"
- "cgroup_enable=memory"
如果文件为空它将不执行任何操作
TASK [Enable container features]
ok: [localhost] => (item=cgroup_enable=cpuset)
ok: [localhost] => (item=cgroup_memory=1)
ok: [localhost] => (item=cgroup_enable=memory)
如果文件中存在该行,则此任务将对其进行更改
shell> cat cmdline.txt
cgroup_enable=cpuset cgroup_memory=1 cgroup_enable=memory
ASK [Enable container features] *****************************************
ok: [localhost] => (item=cgroup_enable=cpuset)
--- before: cmdline.txt
+++ after: cmdline.txt
@@ -1 +1 @@
-cgroup_memory=1 cgroup_enable=memory cgroup_enable=cpuset
+cgroup_memory=1 cgroup_enable=memory cgroup_enable=cpuset cgroup_memory=1