1833276 Members
2928 Online
110051 Solutions
New Discussion

Re: Script help!

 
SOLVED
Go to solution
tom quach_1
Super Advisor

Script help!

Hello all,
Please hekp me to correct this script.

this script will read the file "test_userlist" and create users with 2 comments
But i always receive error below.


#!/usr/bin/sh -x
for user in `cat test_userlist`
NAME=`echo $user | awk -F\: '{print $1}'`
FULLNAME=`echo $user | awk -F\: '{print $2}'`
COUNTRY=`echo $user | awk -F\: '{print $3}'`
do useradd -m -s /usr/bin/false -g sunml -c "${FULLNAME},${COUNTRY}" $NAME

done

the content of file "test_userlist"

sally00:test00:australia
sally01:test01:australia
sally02:test02:australia


received this error when ran it

./cr_user.sh.t[2]: Syntax error at line 4 : `NAME=`echo $user | awk -F: '{print $1}'`' is not expected.


thanks in advance.
Tom
9 REPLIES 9
A. Clay Stephenson
Acclaimed Contributor
Solution

Re: Script help!

You are missing "do"

for user in .....
do
.....
.....
done
If it ain't broke, I can fix that.
Patrick Wallek
Honored Contributor

Re: Script help!

And just to make things much easier to read, everyone should really NOT use the back-ticks (`).

The new way to do this is with the $(statement) syntax.

Your script for example:

#!/usr/bin/sh -x
for user in $(cat test_userlist)
do
NAME=$(echo $user | awk -F\: '{print $1}')
FULLNAME=$(echo $user | awk -F\: '{print $2}')
COUNTRY=$(echo $user | awk -F\: '{print $3}')
useradd -m -s /usr/bin/false -g sunml -c "${FULLNAME},${COUNTRY}" $NAME

done
James R. Ferguson
Acclaimed Contributor

Re: Script help!

Hi Tom:

The use of 'cat' adds another process that isn't needed. In fact, you can do away with 'awk' and use the shell to split your line into component fields:

#!/usr/bin/sh
OLDIFS=${IFS}
IFS=":"
while read NAME FULLNAME COUNTRY X
do
useradd -m -s /usr/bin/false -g sunml -c "${FULLNAME},${COUNTRY}" $NAME
done < test_userlist
IFS=${OLDIFS}
exit 0

Regards!

...JRF...
tom quach_1
Super Advisor

Re: Script help!

Thank you all for your prompt response.

Regards,
Tom
TwoProc
Honored Contributor

Re: Script help!

FWIW,
the "cut" command, when it can be used is much faster than firing up awk for each line.

--- cut example ---
for user in `cat test_userlist`
do
NAME=`echo $user | cut -f1 -d:`
FULLNAME=`echo $user | cut -f2 -d:`
COUNTRY=`echo $user | cut -f3 -d:`
useradd -m -s /usr/bin/false -g sunml -c "${FULLNAME},${COUNTRY}" $NAME
done
----- end of cut example ---


BUT, you could get this done in fewer lines using the "set" command:

----- set example -------
for user in `cat test_userlist`
do
set `echo $user | sed "s/:/ /g"`
useradd -m -s /usr/bin/false -g sunml -c "${2},${3}" $1
done

---- end of set example ----

What the example above is doing is using sed to put spaces between the words so that the shell command "set" would be able to parse the contents of $user into $1, $2 and $3. Then of course those arguments used as would you have with the variables you used for the useradd command ... it's just less readable - as is it seems most things which can be done "quicker" in the shell are.

We are the people our parents warned us about --Jimmy Buffett
TwoProc
Honored Contributor

Re: Script help!

Wow, ... robbed by 1 MINUTE 1!!

:-) :-) :-)
We are the people our parents warned us about --Jimmy Buffett
Dennis Handly
Acclaimed Contributor

Re: Script help!

In regards to JRF's comment about an silly use of cat in Tom's improvements:
for user in $(cat test_userlist)
to: for user in $(< test_userlist)

It seems that Clay was not quite right in the original case. The "do" is there but it is on the wrong line and there is a bunch of missing "`".

In regards to John's comment about cut vs awk, I've found that cut has an interface that is just too complex to understand. awk is simple and doesn't have a problem with "field delimiters delimit null fields".
TwoProc
Honored Contributor

Re: Script help!

Dennis,

you're right, cut is a bit funkier especially when the delimiters are not a single character: that's why I added "when it can be used".

I use awk when the parse is more complex, but when it a simple reliable single character - I'll grab the "cut" command as it really does run much faster, especially when one is looking to parse a large number of lines (like thousands). But, I don't get to use it as often, because data these days don't seem to be laid out as rigourosly in printed record form like in the old IBM mainframe and /or old Fortran days (not that I'm getting wistful for going back to that stuff again).

We are the people our parents warned us about --Jimmy Buffett
tom quach_1
Super Advisor

Re: Script help!

Thanks Dennis

never use this "," before
to: for user in $(< test_userlist)

just learn something new.

Thanks again.
Tom