The basic strategy woudl be to read each
line in a loop:
!#/bin/sh
while read iline
do
echo $iline
done < /etc/inittab
exit 0
In each iteration of the loop, you have the
entire line in the variable $iline.
From this point, the next step is to process
each line in the loop however you need to.
You can use awk for this task if you desire.
I just gave you the very basics as to not give
away all the answers but it's a least a starting
point
thanks rwb, exactly what i was looking for. but i'm stuck there now. i was planning to use grep to anaylze inittab, you know, grep lines that begin with a # and ignore them, check the fields...
but how can I pass each line as the argument to grep?
I tried this way, but i'm not quite where I need to be yet:
#!/bin/ksh
while read iline
do
echo $iline|xargs
echo $*
grep ^# $*
I would use a different approach. I would
use grep to remove all the lines that
start with "#"...
!#/bin/ksh
# create a tmp file with all lines in /etc/inittab
# that do not start with "#"
grep -v ^# /etc/inittab > /tmp/mytest.$$
#loop through each line in the tmp file
while read iline
do
# this is where you would process $iline
# using awk and/or sed is easiest IMHO
...
...
done < /tmp/mytest.$$
# clean up after yourself
rm -f /tmp/mytest.$$
exit 0
...what you do in the processing of each line
is dependent on what "and do various things"
entails. I'd also recommend a careful reading
of the grep man page. There's alot of good stuff
you can do with it. Also, the following URL
is a good online reference for AWK: http://vectorsite.tripod.com/tsawk0.html
I'll use sed and awk when I get more familiar with them, I think grep will work for what I need to do, here's my script so far, with some of the "various things" I want the loop to do included as comments. Your help has made a drastic improvement already, what will the next step be...
#!/bin/ksh
# Usage: chkinit (inittab file)
# This creates a temp file to work with,using all lines
# in the inittab that do not begin with # (assumes the argument is an
# inittab file) and all lines that are not blank
grep -v -e "^#" -e "^$" $1 > /tmp/mytest.$$
# this will loop through each line in the tmp file
while read iline
do
# case (can I use case here... if so how?)
# I would like to: * ensure that all lines contain 4 fields
# * make sure the id field has from 1 to 4 chars
# * make sure that the run levels are valid for
the process indicated
done < /tmp/mytest.$$
Well... I don't believe grep by itself will
give you what you need. This is why I suggest
awk. I myself would in fact use awk for this
sort of thing. ksh itself does not provide
good string handling capabilities (at least not
without alot of excess work). For example,
the resulting lines from /etc/initab may be
somthing like...
...so here you can see you have 4 fields...
id:runlevels:action:process
...separated by a ":" and you need to examine
these individually so you would need to
separate each field into distinct variables.
awk provides simple methods for doing this
very thing (and much much more). You could
perhaps use "case" against a single field
variable (once extracted from the line) to
apply rules that are defined as general for
a given value. Special rules however will
tend to create an overly complex script and
more prone to errors.
Again, my recommendation would be to learn
awk (at least the basics of it) and try some
things. After that if you have more questions,
I'm sure you can get answeres on this forum.
I would just use ksh by itself. It can read each record, split the record into fields, count the characters in a field, etc. In short, it can do everything you need.
Also, remember that lines are not the same as records in inittab. You can end a line with a backslash to continue the record on the next line. Your grep method doesn't handle this.
Yeah, that line is legal and my code will not reject it. It this case nf will be 3 because there are 3 non-empty fields. Only records where nf is 0 are discarded, these are blank lines.
If you leave this field empty, it is the same as specifying "0123456", which means that it will not run in run level s.
I see that it works. But somehow I have to count the empty fields, to make sure that there are 4 fields, empty or not. I tried adding an "or" to the test statement (for fields 2 and 4, which can be blank), like this:
[[ ! -z $rstate -o -z $rstate ]] && ((nf=nf+1))
but it complains about the -o option.
This is the test I put for length of id field,
thanks again.
idlength=$\{\#id\}
if [ $idlength -ne 0 -a $idlength -le 4 ]; then
:
else
echo "id field must be from 1 to 4 characters"
fi
I also need some way to put the line number of a failing line into an echo statement...
Don't do that. The nf stuff is to detect completely blank lines. If you really wanted to unconditionally increment nf at this point, there is no need to add a test that cannot fail. ((nf=nf+1)) could be used all by itself. Add with ksh [[ or it handled by | not -o.
If you don't care whether or not the field rstate has something, just don't test it. Instead, test the stuff you do care about. You are already checking the id field for the number of characters. That leaves the action field. You can just add a "if [[ -z $action ]]" or maybe you'd rather get the length of the action field and see if it's non-zero.