Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Changes to comments in /etc/passwd file 3

Status
Not open for further replies.

grapes12

Technical User
Mar 2, 2010
124
ZA
I need to create a shell script to make changes to the comment field in the /etc/passwd file.
I got the data from the oracle database, and need to make the necessary changes to the /etc/passwd file from a spool file created in oracle
can u please assist in pointing me into the right direction
 
Can you supply samples of the Oracle spool output (de-personalised if necessary), and the exact Unix OS the /etc/passwd is coming from?

The internet - allowing those who don't know what they're talking about to have their say.
 
Herwith output of spool file:
johnnyt SUNDRIES/H/O Johnny Tenner
jayb SUNDRIES/H/O Jayson Basson
yma SUNDRIES/KZN Youshaa Mahomed
johc SUNDRIES/KZN Johann Claassen
its SUNDRIES/GEO Itsetebe Warehouse
patience SUNDRIES/GEO Patience Langa

uname -a
SunOS sun5 5.10 Generic_139555-08 sun4u sparc SUNW,SPARC-Enterprise

The script must be able to pick the username e.g. its
and change the comment field for that username "SUNDRIES/GEO Itsetebe Warehouse"..
thanks
 
Hi

I would do it with [tt]awk[/tt] :
Code:
awk 'FNR==NR{l=$1;sub(l FS"+","");n[l]=$0;next}FNR==1{FS=OFS=":";$0=$0}$1 in n{$5=n[$1]}1' spoolfile /etc/passwd > /tmp//passwd.new

Feherke.
 
Explain please the AWK commnad..i am new to shell scripting..
 
Hi

Code:
awk '
FNR==NR {         [gray]# if processing the first input file[/gray]
  l=$1            [gray]# put 1[sup]st[/sup] field's value in variable l[/gray]
  sub(l FS"+","") [gray]# remove l's value followed by one or more FS[/gray]
  n[l]=$0         [gray]# put in array n at key l the current record[/gray]
  next            [gray]# skip executing the following code[/gray]
}
FNR==1 {          [gray]# if processing the file's first record[/gray]
  FS=OFS=":"      [gray]# set the new field separator[/gray]
  $0=$0           [gray]# re-parse the current record[/gray]
}
$1 in n {         [gray]# if array n contains key equal with the 1[sup]st[/sup] field[/gray]
  $5=n[$1]        [gray]# set 5[sup]th[/sup] field with array n's corresponding value[/gray]
}
1                 [gray]# always do the default action ( print $0 )[/gray]
' spoolfile /etc/passwd > /tmp//passwd.new

Feherke.
 
can u please assist
What have YOU tried so far and where in YOUR code are you stuck ?

Hope This Helps, PH.
FAQ219-2884
FAQ181-2886
 
i had something like this in mind:

#-- Change comment field from input file
LOG_FILE=/usr/local/bin/passwd_comments.lst

result=`grep $1 in `$LOG_FILE | awk -F: '{ print $5 }'`
if [ "$result" ]
then
echo " $result "
fi
/usr/local/sbin/usermod -c

But how would i do it for the whole file?
 
Hi

I would use [tt]read[/tt] in a [tt]while[/tt] loop for that :
Code:
[b]while[/b] [blue]IFS[/blue][teal]=[/teal][green][i]':'[/i][/green] [COLOR=chocolate]read[/color] login pass user group name home shell[teal];[/teal] [b]do[/b]
  [navy]newname[/navy][teal]=[/teal][green][i]"$( grep "[/i][/green][navy]$login[/navy][green][i]" spoolfile | cut -d ' ' -f 2- )"[/i][/green]
  echo [green][i]"$login:$pass:$user:$group:${newname:-$name}:$home:$shell"[/i][/green]
[b]done[/b] [teal]<[/teal] /etc/passwd [teal]>[/teal] /tmp/passwd[teal].[/teal]new
Tested with [tt]bash[/tt] and [tt]mksh[/tt].

Feherke.
 
ok will try that..thanks for the help thus far...
 
would this be the same as your While statement or similar
# --- Change comment field from input file
LOG_FILE=/usr/local/bin/passwd_comments.lst
# --To get the values from your /etc/passwd file, you can use a construct like this :

REC=`grep ^$USER /etc/passwd`
PWDHASH=`echo $REC|cut -d: -f2`
UID=`echo $REC|cut -d: -f3`
GID=`echo $REC|cut -d: -f4`
GECKOS=`echo $REC|cut -d: -f5`
HOMEDIR=`echo $REC|cut -d: -f6`
DEFSHELL=`echo $REC|cut -d: -f7`

#--Then you can modify your record by modifying any of these values and reconstruct it as:

NEWREC=`printf $USER":"$PWDHASH":"$UID":"$GID":$GECKOS:"$HOMEDIR":"$DEFSHELL`


result=`grep $1 in `$LOG_FILE | awk -F: '{ print $5 }'`
if [ "$result" ]
then
echo " $result "
fi
/usr/local/sbin/usermod -c --- I WONT HAVE TO DO THIS RIGHT!

then

LINE=`grep -n ^$USER /etc/passwd|cut -d: -f1`
sed -e "${LINE}d" /etc/passwd > /tmp/passwd.fil
echo $NEWREC >> /tmp/passwd.fil

then dump the contents of the temporary file to the /etc/passwd

cat /tmp/passwd.fil > /etc/passwd

Problem is now to put it all together so that it works...!!!!!
 
#!/bin/sh
PF=/etc/passwd
OFS=$IFS
IFS=':'
while
read user pwdhash uid gid fulln homedir defshell
do
echo $user, $fulln
#if [[ $$fulln -eq 0 ]]
#then
#fi
done < /etc/passwd > /tmp/passwd.new
OFS=$IFS
exit

WHAT DO I DO WITH THE IF,THEN?
 
Is there any reason why you're not using feherke's awk solution? It should be much more efficient than those other methods?

By the way, feherke, neat trick with the $0=$0, I must remember that one!

Annihilannic.
 
Although he explained it, where do i put it in my script?
Must i declare everyline in the passwd file as a variable? If so, how do i change the /etc/passwd file contents and replace it with the file contents i extracted from the oracle listing?
 
All you need to do after running his script (yes, it is just one line of script) is check that /tmp/passwd.new contains all of the changes you want, and then replace /etc/passwd with that new file if it is okay.

The only thing you'll need to change is to replace "spoolfile" with $LOG_FILE.

Annihilannic.
 
Oh Okay, but my senior expects the script to be run on demand, with the changes already incorporated within the passwd file. And that is my dilema
 
If you are satisfied with the way the script works the first time you try it out, then you can easily automate the replacement by adding commands such as these after it:

Code:
cp -p/etc/passwd /etc/passwd.backup
mv /tmp/passwd.new /etc/passwd

I'd highly recommend testing it thoroughly first, because a corrupt /etc/passwd file could be a pain to fix.

Annihilannic.
 
Need some more help
CODE:
1.FILE1=/tmp/passwd_comm.lis
2.FILE2=/tmp/passwd.grapes
3.cp $FILE2 /tmp/passwd.$$.orig
4.
5.for i in `cat $FILE1 | awk '{ print $0 }'`
6.do
7. FIELD1=`cat $FILE1 | grep ${i} |awk -F":" '{ print $3 }'`
8. grep $i ${FILE2}
9. if [ $? -eq 0 ]
10. then
11. usermod -c "${FIELD1}" $i
12. fi
13.done

My FILE1 does not have any field delimiters, but i am able to print them as fields as follows:
awk '{ print $1 }' /tmp/passwd_comm.lis
here is output of file:
andrem ECD/LEP Andre Mazire

samj ECD/LEP samantha.jennings

belinda ECD/LEP Belinda Cage

petra ECD/LEP Petra van Aswegen
HOW CAN I change line 7?
 
Here one way you could write that:

Code:
FILE1=/tmp/passwd_comm.lis
FILE2=/tmp/passwd.grapes
cp $FILE2 /tmp/passwd.$$.orig

# for every user in list file 
while read i FIELD1
do
	# if user exists in password file
	if grep -wq $i ${FILE2}
	then
		# modify the comments field
		usermod -c "${FIELD1}" $i
	fi
done < $FILE1

Annihilannic.
 
Where should the close ](bracket) go in this DO statement:
more test2.ksh
#!/bin/ksh
FILE1=/u1/home/gdg/passwd_comm.txt
FILE2=/u1/home/gdg/passwd.grapes
cp $FILE2 /u1/home/gdg/passwd.$$.orig

while IFS=":" read user comment
do
[ -z "grep $user: /u1/home/gdg/passwd.grapes | awk -F: '{print $2}'"
&& usermod -c "$comment" $user
done <$FILE1
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top