Often, when editing a config file from a program, one also wants to leave a comment alongside the change.
When the change adds something to the config file, that’s fairly simple. For example, to add a new entry to /etc/sysctl.conf that sets
vm.mmap_min_addr to 64k and puts a comment just before it, you’d do the following in
augtool (I show augtool commands here, though in reality you’d probably use the Augeas API from your program; I also add line numbers as (N) for easier reference):
augtool(1)> defvar s /files/etc/sysctl.conf augtool(2)> set $s/vm.mmap_min_addr 65536 augtool(3)> ins #comment before $s/vm.mmap_min_addr augtool(4)> set $s/#comment[last()] "Never mmap into the first 64k of memory" augtool(5)> save
Expressed in English, it does the following: (1) define the variable s as a shorthand for where the contents of /etc/sysctl.conf show up in the tree. (2) Set the entry vm.mmap_min_addr to 65536 — since it’s a new entry, Augeas will append it to the very end of /etc/sysctl.conf. (3) Insert a new node #comment just before the vm.mmap_min_addr entry. (4) Assign some useful text to that new comment. (5) Save all the changes; this adds two lines to /etc/sysctl.conf:
# Never mmap into the first 64k of memory vm.mmap_min_addr = 65536
Where it gets interesting is when we try to change an existing entry, for example to turn on kernel.sysrq, and want to change the comment preceding it, too. That’s a change that’s more complicated than it seems at first blush — try writing a little awk or python script that does that before reading on. Assume we have
# Controls the System Request debugging functionality of the kernel kernel.sysrq = 0
somewhere in /etc/sysctl.conf and want to change it to
# Do something fun with that SysRq key kernel.sysrq = 1
The steps above almost work, with the exception of changing the comment. Above, we referred to the comment as $s/#comment[last()], i.e. we really said “change the very last comment in the file”, which just happened to be the right one. Now, we don’t know where in the file kernel.sysrq is, and it’s unlikely that its comment is the very last comment in the file. With a patch that I just committed, and that will be in Augeas 0.5.3, it’s now possible to find that comment by using the following-sibling axis in a path expression, i.e. by looking at all the nodes that come after a given node. To be precise, we’d do the following in augtool:
augtool(1)> defvar s /files/etc/sysctl.conf augtool(2)> set $s/kernel.sysrq 1 augtool(3)> set $s/#comment[following-sibling::*[self::kernel.sysrq]] \ "Do something fun with that SysRq key" augtool(4)> save
The path expression in step (3) says roughly “take the #comment node that is immediately followed by the kernel.sysrq node” — the ”… is immediately followed by …” is expressed by the following-sibling::*, as that picks the first sibling after the current node.
Four lines with augtool (and the same four lines through the Augeas API from C or Python) is about as compact as one can make that change.