4 augprint - create an idempotent augtool script for a given file
8 augprint [--pretty|-p] [--regexp[=n]|-r[n]] [--noseq|-s] [--verbose|-v] [--lens name|-l name] [--target /target|-t /target] FILE
12 B<augprint> creates an augtool script for a given B<FILE>
13 consisting primarily of C<set> commands.
15 The resulting augtool script is designed to be idempotent, and
16 will not result in any changes when applied to the original file.
18 B<augprint> replaces each numbered location in the tree with
19 a path-expression that uniquely identifies the position using the values
20 I<within> that position.
22 This makes the path-expression independant of the position-number,
23 and thereby applicable to files which in which the same data may exist at
24 an alternate position-number
26 See "Examples" for sample output
30 By default B<augprint> produces path-expressions made up of simple equality C<=> comparisions
32 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/ipaddr '127.0.0.1'
34 The option B<--regexp> changes the output to produce regular expression comparisions
36 set /files/etc/hosts/seq::*[ipaddr=~regexp('127\\.0\\..*')]/ipaddr '127.0.0.1'
38 The minimum length I<N> of the regular expression can be specified using C<--regexp=N>
40 B<augprint> will choose a longer regular expression than I<N> if multiple values
41 would match using the I<N> character regular expression.
47 The output is based primarily on set operations.
48 The set operation can only:
50 a) change an existing value in-situ
52 b) append a new value after the last position in the group
54 This means that when an entry is re-created, it may not be in the same position as originally intended.
55 ie if the entry for C<192.0.2.3> does not already exist, it will be created as the I<last> entry in F</etc/hosts>
57 Often, such out-of-sequence entries will not matter to the resulting configuration file.
58 If it does matter, further manual editing of the C<augtool> script will be required.
60 =head3 Repeated Values
62 B<augprint> is not always successful in finding a path-expression which is unique to a position.
63 In this case B<augprint> appends a position to an expression which is not unique
65 This occurs in particular if there are repeated values within the file.
67 For an F</etc/hosts> file of
73 B<augprint> would produce the output
75 set /files/etc/hosts/#comment[.='--------'][1] '--------'
76 set /files/etc/hosts/seq::*[ipaddr='192.0.2.3']/ipaddr '192.0.2.3'
77 set /files/etc/hosts/seq::*[ipaddr='192.0.2.3']/canonical 'defaultdns'
78 set /files/etc/hosts/#comment[.='--------'][2] '--------'
80 Notice how C<#comment> paths have C<[1]> and C<[2]> appended respectively to the C<[expr]>
82 Other paths which do have unique path-expressions are not directly affected
89 =item B<-v>, B<--verbose>
91 Include the original numbered paths as comments in the output
93 =item B<-p>, B<--pretty>
95 Create more readable output by adding spaces and empty lines
97 =item B<-r>, B<-r>I<N>, B<--regexp>, B<--regexp>=I<N>
99 Generate regular expressions to match values,
100 using a minumum length of I<N> characters from the value
102 I<N> can be omitted and defaults to 8
104 =item B<-l>, B<--lens>=I<LENS>
106 Use I<LENS> for the given file; without this option, B<augprint> uses the
107 default lens for the file
109 =item B<-t> I<targetfile>, B<--target>=I<targetfile>
111 Generate the script for the I<FILE> specified as if its path was really I<targetfile>
113 This will apply the lens corresponding to I<targetfile> to I<FILE>
114 and modifying the resulting path-expressions of I<FILE> to correspond to I<targetfile>
116 I<targetfile> must be the full path name, starting with a '/'
118 See "Examples" for how B<--target> can be used in practice
120 =item B<-s>, B<--noseq>
122 Do not use C<seq::*> in the output, use C<*> instead.
125 set /files/etc/hosts/*[ipaddr='127.0.0.1']/ipaddr '127.0.0.1'
127 IMPORTANT: The resulting output will no longer I<create> a new entry
128 for C<127.0.0.1> if none already exists. The C<--noseq> option exists so
129 that the resulting paths can be used with augeas versions prior to 1.13.0
130 (subject to this limitation)
136 These examples use the following F</etc/hosts> file as the I<FILE>
138 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
142 The output from C<augtool 'print /files/etc/hosts'> would be
146 /files/etc/hosts/1/ipaddr = "127.0.0.1"
147 /files/etc/hosts/1/canonical = "localhost"
148 /files/etc/hosts/1/alias[1] = "localhost.localdomain"
149 /files/etc/hosts/1/alias[2] = "localhost4"
150 /files/etc/hosts/1/alias[3] = "localhost4.localdomain4"
152 /files/etc/hosts/2/ipaddr = "192.0.2.3"
153 /files/etc/hosts/2/canonical = "dns-a"
155 /files/etc/hosts/3/ipaddr = "192.0.2.4"
156 /files/etc/hosts/3/canonical = "dns-b"
158 =head2 Default output
160 C<augprint /etc/hosts>
162 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/ipaddr '127.0.0.1'
163 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/canonical 'localhost'
164 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/alias[.='localhost.localdomain'] 'localhost.localdomain'
165 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/alias[.='localhost4'] 'localhost4'
166 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/alias[.='localhost4.localdomain4'] 'localhost4.localdomain4'
167 set /files/etc/hosts/seq::*[ipaddr='192.0.2.3']/ipaddr '192.0.2.3'
168 set /files/etc/hosts/seq::*[ipaddr='192.0.2.3']/canonical 'dns-a'
169 set /files/etc/hosts/seq::*[ipaddr='192.0.2.4']/ipaddr '192.0.2.4'
170 set /files/etc/hosts/seq::*[ipaddr='192.0.2.4']/canonical 'dns-b'
172 =head2 Verbose output
174 C<augprint --verbose /etc/hosts>
178 # /files/etc/hosts/1/ipaddr '127.0.0.1'
179 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/ipaddr '127.0.0.1'
180 # /files/etc/hosts/1/canonical 'localhost'
181 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/canonical 'localhost'
182 # /files/etc/hosts/1/alias[1] 'localhost.localdomain'
183 set /files/etc/hosts/seq::*[ipaddr='127.0.0.1']/alias[.='localhost.localdomain'] 'localhost.localdomain'
188 C<augprint --regexp=4 /etc/hosts>
190 set /files/etc/hosts/seq::*[ipaddr=~regexp('127\\..*')]/ipaddr '127.0.0.1'
191 set /files/etc/hosts/seq::*[ipaddr=~regexp('127\\..*')]/canonical 'localhost'
192 set /files/etc/hosts/seq::*[ipaddr=~regexp('127\\..*')]/alias[.=~regexp('localhost\\..*')] 'localhost.localdomain'
193 set /files/etc/hosts/seq::*[ipaddr=~regexp('127\\..*')]/alias[.=~regexp('localhost4')] 'localhost4'
194 set /files/etc/hosts/seq::*[ipaddr=~regexp('127\\..*')]/alias[.=~regexp('localhost4\\..*')] 'localhost4.localdomain4'
195 set /files/etc/hosts/seq::*[ipaddr=~regexp('192\\.0\\.2\\.3')]/ipaddr '192.0.2.3'
196 set /files/etc/hosts/seq::*[ipaddr=~regexp('192\\.0\\.2\\.3')]/canonical 'dns-a'
197 set /files/etc/hosts/seq::*[ipaddr=~regexp('192\\.0\\.2\\.4')]/ipaddr '192.0.2.4'
198 set /files/etc/hosts/seq::*[ipaddr=~regexp('192\\.0\\.2\\.4')]/canonical 'dns-b'
200 Note that although a I<minimum> length of 4 has been specified, B<augprint> will choose longer regular expressions
201 as needed to ensure a unique match.
205 If a file is not assocatiated with a lens by default, I<--lens lensname> can be used to specify a lens.
207 When I<--lens> is specified, the output is prefixed with suitable C<transform> and C<load-file> statements,
208 as required to complete the augtool script, and a I<setm> statement to exclude other autoloaded lenses.
210 C<augprint --lens shellvars /etc/skel/.bashrc>
212 setm /augeas/load/*[incl='/etc/skel/.bashrc' and label() != 'shellvars']/excl '/etc/skel/.bashrc'
213 transform shellvars incl /etc/skel/.bashrc
214 load-file /etc/skel/.bashrc
215 set /files/etc/skel/.bashrc/#comment[.='.bashrc'] '.bashrc'
216 set /files/etc/skel/.bashrc/#comment[.='Source global definitions'] 'Source global definitions'
217 set /files/etc/skel/.bashrc/@if[.='[ -f /etc/bashrc ]'] '[ -f /etc/bashrc ]'
218 set /files/etc/skel/.bashrc/@if[.='[ -f /etc/bashrc ]']/.source '/etc/bashrc'
219 set /files/etc/skel/.bashrc/#comment[.='User specific environment'] 'User specific environment'
222 The lenses C<simplelines> C<shellvars> are most commonly useful as lenses for files that do not have
225 =head2 Using --target
227 In order to prepare an augtool script intended for a given file, it may be desired to
228 copy the file to another location, rather than editting the original file.
230 The option I<--target> simplifies this process.
232 a) copy F</etc/hosts> to a new location
236 b) edit F<~/hosts> to suit
238 echo '192.0.2.7 defaultdns' >> ~/hosts
240 c) Run C<augprint> as follows
242 augprint --target /etc/hosts ~/hosts
244 d) Copy the relevant part of the output to an augtool script or other Augeas client
246 set /files/etc/hosts/seq::*[ipaddr='192.0.2.7']/ipaddr '192.0.2.7'
247 set /files/etc/hosts/seq::*[ipaddr='192.0.2.7']/canonical 'defaultdns'
249 Notice that C<augprint> has generated paths corresponding to I<--target> (/etc/hosts) instead of the I<FILE> argument (~/hosts)
253 =head1 ENVIRONMENT VARIABLES
259 The effective file system root, defaults to '/'.
261 =item B<AUGEAS_LENS_LIB>
263 Colon separated list of directories with lenses. Directories specified here
264 are searched before the default directories F</usr/share/augeas/lenses> and
265 F</usr/share/augeas/lenses/dist>
271 The exit status is 0 when the command was successful
272 and 1 if any error occurred.
276 Lenses and schema definitions in F</usr/share/augeas/lenses> and
277 F</usr/share/augeas/lenses/dist>
281 George Hansper <george@hansper.id.au>
283 =head1 COPYRIGHT AND LICENSE
285 Copyright 2022 George Hansper
287 Augeas (and augprint) are distributed under the GNU Lesser General Public
288 License (LGPL), version 2.1
294 B<Augeas> project homepage L<https://www.augeas.net/>
296 B<Augeas> path expressions L<https://github.com/hercules-team/augeas/wiki/Path-expressions>