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 (cfengine-Tutorial).
AbortAtLineMatching
quoted-regexFixEndOfLine
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-stringBeginGroupIfNoLineMatching
and
BreakIfLineMatches
.
AppendIfNoSuchLine
quoted-stringAppendIfNoLineMatching
quoted-regexAppendIfNoSuchLine
which uses a regular expression instead of a literal
string. The line which gets appended must be set
previously using SetLine
.
AppendToLineIfNotContains
quoted-stringAutoCreate
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-stringRepository
quoted stringRepository
variable, on an item
by item basis. If set to "off" or "none" it cancels the value of a global repository.
BeginGroupIfFileExists
quoted-stringEndGroup
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-stringEndGroup
are executed if the quoted filename is newer than the file being
edited.
BeginGroupIfNoLineContaining
quoted-stringEndGroup
are executed if the quoted string does not appear in
any line in the file.
BeginGroupIfNoLineMatching
quoted-regexEndGroup
are executed if the quoted regular expression
does not match any line in the file.
BeginGroupIfNoMatch
quoted-regexEndGroup
are executed if the quoted regular expression does
not match the current line.
BeginGroupIfNoSuchLine
quoted-stringEndGroup
are executed if the quoted literal string
does not match any line in the file.
BreakIfLineMatches
quoted-regexCatchAbort
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-regexSetCommentStart
and SetCommentEnd
to comment
out lines matching the given regular expression in quotes.
CommentLinesStarting
quoted-stringSetCommentStart
and SetCommentEnd
to comment
out lines starting with the quoted literal string.
CommentNLines
quoted-stringSetCommentStart
).
After the operation the pointer points to the line after the
commented lines.
CommentToLineMatching
quoted-regexSetCommentStart
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-stringDeleteLinesMatching
quoted-regexDeleteLinesStarting
quoted-stringDeleteNLines
quoted-stringDeleteToLineMatching
quoted-regexEmptyEntireFilePlease
ElseDefineClasses
DefineClasses
EndGroup
EndLoop
ForEachLineIn
Filter
filteraliasFixEndOfLine
ForEachLineIn
quoted-filenameSetLine
for each line in the file. Nested loops are not permitted.
GotoLastLine
HashCommentLinesContaining
quoted-stringHashCommentLinesMatching
quoted-regexHashCommentLinesStarting
quoted-stringIncrementPointer
quoted-numberInform
quoted-stringInsertFile
quoted-stringInsertLine
quoted-stringLocateLineMatching
quoted-stringWarnIfNoLineMatching
so that you can get an explicit warning, even
out of verbose mode.
PercentCommentLinesContaining
quoted-stringPercentCommentLinesMatching
quoted-regexPercentCommentLinesStarting
quoted-stringPrepend
quoted-stringBeginGroupIfNoLineMatching
and
BreakIfLineMatches
.
PrependIfNoLineMatching
quoted-regexPrependIfNoSuchLine
with uses a regular expression instead of a literal string.
The string prepended is the one set using SetLine
.
PrependIfNoSuchLine
quoted-stringRecurse
digit/infReplaceLineWith
quoted-stringReplaceAll
quoted-regex With
quoted-stringReplaceLinesMatchingField
quoted-numberSetLine
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-stringRunScript
quoted-stringCAUTION: 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-stringSetScript
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-regexSetScript
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-stringCommentLineMatching
and CommentLineStarting
. The default is the hash
symbol # followed by a single space.
SetCommentEnd
quoted-stringCommentLineMatching
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-stringAppendIfNoLineMatching
using a regular expression.
SetScript
quoted-stringSlashCommentLinesContaining
quoted-stringSlashCommentLinesMatching
quoted-regexSlashCommentLinesStarting
quoted-stringSplitOn
quoted-stringReplaceLinesMatchingField
.
Syslog
quoted-stringUmask
quote modeUnCommentLinesContaining
quoted-stringUnCommentLinesMatching
quoted-regexUnCommentNLines
quoted-stringUnCommentNLines "3"
would
uncomment
/* 1 */ /* 2 */ /* 3 */
and also
/* 1 2 3 */
UnsetAbort
quoted-stringAbortAtLineMatching
.
WarnIfLineContaining
quoted-stringWarnIfLineMatching
quoted-regexWarnIfLineStarting
quoted-stringWarnIfNoLineContaining
quoted-stringWarnIfNoLineMatching
reg-exWarnIfNoLineStarting
quoted-stringWarnIfNoSuchLine
quoted-regexA 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
literalBinaryPaddingChar
in control
.
Padding with a null byte would lead to corruption of text within a program.
WarnIfContainsString
regex/literalWarnIfContainsFile
filenameIt 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.