Performs ascii (line-based) editing on text-files or limited binary
editing of files.
If editing a file which has hard links to it, be aware that
editing the file will destroy the hard link references. This is also the
case with shell commands. You should avoid hard links whenever possible.
The form of an editing command is
editfiles
can also search directories recursively through directories
and edit all files matching a pattern, using Include
, Exclude
, and
Ignore
(see Recursive File Sweeps in the tutorial).
editfiles: class:: { file-to-be-edited action "quoted-string..." } { directory-to-be-edited Recurse "inf" Filter "filteralias" Include ".cshrc" Ignore "bin" Ignore ".netscape" action "quoted-string..." } |
Here are some examples:
editfiles: sun4:: { /etc/netmasks DeleteLinesContaining "255.255.254.0" AppendIfNoSuchLine "128.39 255.255.255.0" } PrintServers:: { /etc/hosts.lpd AppendIfNoSuchLine "tor" AppendIfNoSuchLine "odin" AppendIfNoSuchLine "borg" }
The first of these affects the file /etc/netmasks
on all SunOS 4
systems, deleting any lines containing the string "255.255.254.0" and
Appending a single line to the file containing "128.39 255.255.255.0"
if none exists already. The second affects only hosts in the class
`PrintServers' and adds the names of three hosts: tor, odin and borg to
the file /etc/hosts.lpd
which specifies that they are allowed to
connect to the printer services on any host in the class `PrintServers'.
Note that single or double quotes may be used to enclose strings in cfengine. If you use single quotes, your strings may contain double quotes and vice-versa. Otherwise a double quoted string may not currently contain double quotes and likewise for single quoted strings.
As of version 1.3.0, you can use the home
directive in
edit filenames, enabling you to edit files for every user
on the system, provided they exist. For example, to edit
every user's login files, you would write
{ home/.cshrc AppendIfNoSuchLine "setenv PRINTER default-printer" AppendIfNoSuchLine "set path = ( $path /new/directory )" }
If a user does not possess the named file, cfengine just skips that user. A new file is not created.
The meanings of the file-editing actions should be self-explanatory.
Commands containing the word 'comment' are used to `comment out' certain
lines in a file rather than deleting them. Hash
implies a shell
comment of the type
# comment
Slash
implies a comment of the C++ type:
// comment
Percent
implies a comment of the type:
% comment
More general comment types may be defined using the
SetCommentStart
, SetCommentEnd
and
CommentLinesMatching
, CommentLinesStarting
functions.
A special group of editing commands is based on the GNU Regular
Expression package. These use GNU regular expressions to search line by
line through text and perform various editing functions. Some of these
commands are based on the concept of a file pointer. The pointer starts
at line one of the file and can be reset by 'locating' a certain line,
or by using the reset-pointer commands. The current position of the
pointer is used by commands such as InsertLine
to allow a
flexible way of editing the middle of files.
A simple decision mechanism is incorporated to allow certain editing actions to be excluded. For instance, to insert a number of lines in a file once only, you could write:
{ file LocateLineMatching "insert point..." IncrementPointer "1" BeginGroupIfNoMatch "# cfengine - 2/Jan/95" InsertLine "# cfengine - 2/Jan/95" InsertLine "/local/bin/start-xdm" EndGroup }
Since the first inserted line matches the predicate on subsequent calls, the grouped lines will only be carried out once.
The full list of editing actions is given below in alphabetical order.
Note that some commands refer to regular expressions and some refer to
'literal strings' (i.e. any string which is not a regular
expression). Variable substitution is performed on all strings. Be
aware that symbols such as .
, *
and so on are
meta-characters in regular expressions and a backslash must be used to
make them literal. The regular expression matching functions are
POSIX extended regular expressions.
See Regular expressions.
AbortAtLineMatching
quoted-regex
FixEndOfLine
and GotoLastLine
) which involve multiple
replacements and searches, this expression marks a boundary
beyond which cfengine will cease to look any further. In other
words, if cfengine encounters a line matching this regular
expression, it aborts the current action. BE CAREFUL with this
feature: once set, the string remains set for the remainder of
the current file. It might therefore interact in unsuspected ways
with other search parameters. Editing actions are always aborted
as soon as the abort expression is matched.
Use UnsetAbort
to unset the feature.
Append
quoted-string
BeginGroupIfNoLineMatching
and
BreakIfLineMatches
.
AppendIfNoSuchLine
quoted-string
AppendIfNoLineMatching
quoted-regex
AppendIfNoSuchLine
which uses a regular expression instead of a literal
string. The line which gets appended must be set
previously using SetLine
.
AppendToLineIfNotContains
quoted-string
AutoCreate
AutomountDirectResources
quoted-string
"-nosuid"
for non setuid mounting (of all the
mountables). Note that this is added to the current file and not to a
file named /etc/auto_direct
.
Backup
quoted-string
Repository
quoted string
Repository
variable, on an item
by item basis. If set to "off" or "none" it cancels the value of a global repository.
BeginGroupIfFileExists
quoted-string
EndGroup
are executed if the quoted filename exists (can be statted).
Files which are not readable by the running process are
for all intents and purposes non-existent.
BeginGroupIfFileIsNewer
quoted-string
EndGroup
are executed if the quoted filename is newer than the file being
edited.
BeginGroupIfNoLineContaining
quoted-string
EndGroup
are executed if the quoted string does not appear in
any line in the file.
BeginGroupIfNoLineMatching
quoted-regex
EndGroup
are executed if the quoted regular expression
does not match any line in the file.
BeginGroupIfNoMatch
quoted-regex
EndGroup
are executed if the quoted regular expression does
not match the current line.
BeginGroupIfNoSuchLine
quoted-string
EndGroup
are executed if the quoted literal string
does not match any line in the file.
BreakIfLineMatches
quoted-regex
CatchAbort
LocateLineMatching
)
will jump to the first instance of this marker instead of completely
aborting an edit if this keyword occurs in an editing script.
You can catch the exceptions thrown by the following commands:
CommentNLines
,CommentToLineMatching
,DeleteNLines
,DeleteToLineMatching
,
HashCommentToLineMatching
,IncrementPointer
,
LocateLineMatching
,PercentCommentToLineMatching
,
RunScriptIf(No)LineMatching
,UnCommentNLines
.
CommentLinesMatching
quoted-regex
SetCommentStart
and SetCommentEnd
to comment
out lines matching the given regular expression in quotes.
CommentLinesStarting
quoted-string
SetCommentStart
and SetCommentEnd
to comment
out lines starting with the quoted literal string.
CommentNLines
quoted-string
SetCommentStart
).
After the operation the pointer points to the line after the
commented lines.
CommentToLineMatching
quoted-regex
SetCommentStart
and SetCommentEnd
to comment out lines
from the current position in a file to a line matching the given regular
expression in quotes.
DefineClasses "
class1:
class2:..."
DeleteLinesAfterThisMatching
quoted-regex
DeleteLinesContaining
quoted-string
DeleteLinesMatching
quoted-regex
DeleteLinesStarting
quoted-string
DeleteNLines
quoted-string
DeleteToLineMatching
quoted-regex
EmptyEntireFilePlease
ElseDefineClasses
DefineClasses
EndGroup
EndLoop
ForEachLineIn
Filter
filteralias
FixEndOfLine
dos
or unix
to fix the end of line character conventions
to match these systems. This command should be executed
last of all, since cfengine appends new lines with the conventions
of the system on which is was complied during edit operations.
ForEachLineIn
quoted-filename
SetLine
for each line in the file. Nested loops are not permitted.
GotoLastLine
HashCommentLinesContaining
quoted-string
#
to the start of any line containing the quoted string.
HashCommentLinesMatching
quoted-regex
#
to the start of any line exactly matching the quoted regular expression.
HashCommentLinesStarting
quoted-string
#
to the start of any line starting with the quoted string.
IncrementPointer
quoted-number
"4"
.
Negative values are equivalent to decrementing the
pointer. If a request is made to increment/decrement
outside of the file boundaries the pointer `bumps'
into the boundary and remains there, i.e. either at
start of file or end of file.
Inform
quoted-string
InsertFile
quoted-string
InsertLine
quoted-string
LocateLineMatching
quoted-string
WarnIfNoLineMatching
so that you can get an explicit warning, even
out of verbose mode.
PercentCommentLinesContaining
quoted-string
%
to the start of any line containing the quoted string.
PercentCommentLinesMatching
quoted-regex
%
to the start of any line exactly matching the quoted regular.
PercentCommentLinesStarting
quoted-string
%
to the start of any line starting with the quoted string.
Prepend
quoted-string
BeginGroupIfNoLineMatching
and
BreakIfLineMatches
.
PrependIfNoLineMatching
quoted-regex
PrependIfNoSuchLine
with uses a regular expression instead of a literal string.
The string prepended is the one set using SetLine
.
PrependIfNoSuchLine
quoted-string
Recurse
digit/inf
ReplaceLineWith
quoted-string
ReplaceAll
quoted-regex With
quoted-string
cf.*
with CFENGINE
and cfengine encounters a line hello cfengine cfengine
, then this
will be replaced with hello CFENGINE
even though two possible
strings match the regular expression. On the other hand if the
expression is not ambiguous, say replacing cfengine
with
CFENGINE
, then the result would be hello CFENGINE CFENGINE
.
ReplaceLinesMatchingField
quoted-number
SetLine
or ForEachLineIn
, if the lines
are split into fields (e.g. the password file) separated by the
SplitOn
character (':' by default), and the corresponding
fields match.
The idea behind this command was to be able to override global
passwords (from a file which gets distributed) by new passwords
in a local file. Rather than maintaining the files separately,
this simply overrides the entries with the new ones See FAQS and Tips.
ResetSearch
quoted-string
EOF
indicates the end of
the file.
RunScript
quoted-string
CAUTION: cfengine knows nothing about
the success or failure of anything that is done during the
execution of user scripts. This feature is to be
used at the users own peril!
RunScriptIfLineMatching
quoted-string
SetScript
command only if the current file contains a line matching
the quoted regular expression.
CAUTION: cfengine knows nothing about
the success or failure of anything that is done during the
execution of user scripts. This feature is to be
used at the users own peril!
RunScriptIfNoLineMatching
quoted-regex
SetScript
command if the current file contains no line matching
the quoted regular expression.
CAUTION: cfengine knows nothing about
the success or failure of anything that is done during the
execution of user scripts. This feature is to be
used at the users own peril!
SetCommentStart
quoted-string
CommentLineMatching
and CommentLineStarting
. The default is the hash
symbol #
followed by a single space.
SetCommentEnd
quoted-string
CommentLineMatching
and CommentLineStarting
. The default is the empty
string. For example, you could make C style comments
by setting CommentStart to /*
and comment
end to */
.
SetLine
quoted-string
AppendIfNoLineMatching
using a regular expression.
SetScript
quoted-string
SlashCommentLinesContaining
quoted-string
//
to the start of any line containing the quoted string.
SlashCommentLinesMatching
quoted-regex
//
to the start of any line exactly matching the quoted regular expression.
SlashCommentLinesStarting
quoted-string
//
to the start of any line starting with the quoted string.
SplitOn
quoted-string
:
, as is used in the password and group files.
It is used in conjunction with ReplaceLinesMatchingField
.
Syslog
quoted-string
Umask
quote mode
UnCommentLinesContaining
quoted-string
UnCommentLinesMatching
quoted-regex
UnCommentNLines
quoted-string
/*
and */
comments, the command UnCommentNLines "3"
would
uncomment
/* 1 */ /* 2 */ /* 3 */
and also
/* 1 2 3 */
UnsetAbort
quoted-string
AbortAtLineMatching
.
WarnIfLineContaining
quoted-string
WarnIfLineMatching
quoted-regex
WarnIfLineStarting
quoted-string
WarnIfNoLineContaining
quoted-string
WarnIfNoLineMatching
reg-ex
WarnIfNoLineStarting
quoted-string
WarnIfNoSuchLine
quoted-regex
A limited number of operations can also be performed on purely binary files, e.g.
compiled programs, in order to search for strings or viral code, or to modify
strings within a program. Binary mode is a mutually exclusive, separate mode to normal
editing. The limit on the size of binary files is set by editbinaryfilesize
in control
.
ReplaceAll
regex With
literal
BinaryPaddingChar
in control
.
Padding with a null byte would lead to corruption of text within a program.
WarnIfContainsString
regex/literal
WarnIfContainsFile
filename
It is suggested that you use these editing functions with caution. Although all possible safeguards have been incorporated into them, it is still possible through carelessness to do damage to important files on your system. Always test editing programs carefully before committing them to your global site configuration.