blaztoff
asked on
Delete a Line in Passwd file
I am trying to write a function that will search the passwd file for a string. if it finds it it will prompt you to delete it. If user says yes, it will delete if no then moves on to next match. I almost have it working but for some reason it does not delete the file and actually adds a bunch of string that make up the location of the temp file to the passwd file Here is my code. Its got to be simple of what i am doing wrong
remove(){
TMP1=temp1
TMP2=temp2
cp $file $TMP1 2> /dev/null
grep $1 $TMP1 > $TMP2 2> /dev/null
#use exec and read what you found;
exec 5< $TMP2
#Read line
while read LINE <&5
do
echo $LINE
promptYESNO "Delete this entry" "n"
if [ $YESNO = "y" ] ; then
grep -v $LINE $TMP1 > $TMP1.new 2>/dev/null
mv $TMP1.new $TMP1 2> /dev/null
fi
done
exec 5<&-
mv $file $file.bak
mv $TMP1 $file
}
Well,
when you say that grep -v string temp1 works while grep -v "$LINE" $TMP1 doesn't, there must be a difference between string1 and $TMP.
What does echo $TMP1 say? What's in string?
Maybe the solution could be as simple as putting $TMP1 in quotes ( "$TMP1" )?
wmp
when you say that grep -v string temp1 works while grep -v "$LINE" $TMP1 doesn't, there must be a difference between string1 and $TMP.
What does echo $TMP1 say? What's in string?
Maybe the solution could be as simple as putting $TMP1 in quotes ( "$TMP1" )?
wmp
Is TEMP set as a variable, or it is TEMP1?
... sorry, of course I meant to write ... a difference between string1 and $LINE...
can you do
bash -x scriptname
and post output with samples of passwd files before and after
bash -x scriptname
and post output with samples of passwd files before and after
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
TinTin, won't sed delete all instances of that string in the file? I will give it a try
The way my flow works is that first I grep for all instances of a string from TMPF1 and then pass those results to TMPF2 that way if I grep for sam I will get sam samantha and anything else.
The while loop reads TMPF2 into screen prompt. if you like the result and want to delete it it then will grep -v the LINE result into a TMPF1.new so now I am missing LINE. from TMPF1.new. I then move TMPF1.new to TMPF1 so that TMPF1 now is minus the LINE. I then continue the while loop reading from all of my results from my First grep and slowly getting rid of the lines I do not want from my original TMPF1 file. But my grep -v LINE does not seem to work. The LINE looks correct and it is the LINE that should be deleted and when the grep -v runs I can see that LINE in the TMPF1.new file.
I will post a snippet of some passwd file to search in or you can do a tail on your paswd file to a temp file and try it.
Thanks for the help
The way my flow works is that first I grep for all instances of a string from TMPF1 and then pass those results to TMPF2 that way if I grep for sam I will get sam samantha and anything else.
The while loop reads TMPF2 into screen prompt. if you like the result and want to delete it it then will grep -v the LINE result into a TMPF1.new so now I am missing LINE. from TMPF1.new. I then move TMPF1.new to TMPF1 so that TMPF1 now is minus the LINE. I then continue the while loop reading from all of my results from my First grep and slowly getting rid of the lines I do not want from my original TMPF1 file. But my grep -v LINE does not seem to work. The LINE looks correct and it is the LINE that should be deleted and when the grep -v runs I can see that LINE in the TMPF1.new file.
I will post a snippet of some passwd file to search in or you can do a tail on your paswd file to a temp file and try it.
Thanks for the help
>TinTin, won't sed delete all instances of that string in the file?
Correct. It effectively does the same as grep -v, but allows you to do inline editing and no need for all those temporary files.
Correct. It effectively does the same as grep -v, but allows you to do inline editing and no need for all those temporary files.
ASKER
Hi TinTin, I tried your solution but the Prompt exits to quickly. It does not stop and let me say y or no
Do you have
read YESNO </dev/tty
in your promptYESNO function?
read YESNO </dev/tty
in your promptYESNO function?
ASKER
Hi TinTin, when I ran it with the -i option I got a sed error - wrong usage. So I reran it with it deleted. I got the following error.
sed: Function /test2:*:20000:30000:test cannot be parsed
This is my function below
sed: Function /test2:*:20000:30000:test cannot be parsed
This is my function below
file=passwd.test
remove(){
grep $1 $file | while read LINE
do
echo $LINE
promptYESNO "Delete This entry" "n"
read YESNO </dev/tty
[ $YESNO = "y" ] && sed /$LINE/D $file
done
}
ASKER
I added sed '/$LINE/D' $file and it did not give me the error. However it also did not delete the line though. And when i tried to redirect the output to another file I got a blank file. Not sure why it did this. Maybe something is happening to the $LINE within the sed? when I tried to out double quotes around it I got a parse error again. it only worked with Single quotes.
I tested it with a passwd line like this.
yyyyyy:*:29189:579:yyyyy yyyyyy:/home/yyyyyy:/usr/b in/bash
xxxxx:*:20000:30000:xxxxx xxxxx:/home/xxxxx:/usr/bin /bash
and then ran remove xxxx from anoether file. The file withe the users is not working.
I tested it with a passwd line like this.
yyyyyy:*:29189:579:yyyyy yyyyyy:/home/yyyyyy:/usr/b
xxxxx:*:20000:30000:xxxxx xxxxx:/home/xxxxx:/usr/bin
and then ran remove xxxx from anoether file. The file withe the users is not working.
So this is not on a Linux system then?
ASKER
Ok I confirmed what is happening.
The sed is looking at the values in the $LINE and seeing the / and not working.
I manually put a string value in the sed '/test/d' and it deleted the line
When I put the string value that the grep had done it did nothing. Could it be seeing the
/ in :/home/xxxxx:/usr/b and not finding the match?
The sed is looking at the values in the $LINE and seeing the / and not working.
I manually put a string value in the sed '/test/d' and it deleted the line
When I put the string value that the grep had done it did nothing. Could it be seeing the
/ in :/home/xxxxx:/usr/b and not finding the match?
ASKER
HP-UX
ASKER
Hi TinTin I think i discovered why it was not working with sed. The Password file has special characters in it. When I tried using double quotes around the $LINE it was taking the special characters literally and was actually sending me back a error. When i tried using single quotes it was not using any expansion hence I was getting nothing. I managed to solve it with grep for suture reference for anyone.
cat $passwd_file | while read LINE
do
`echo $LINE | grep $1 > /dev/null`
if [ $? -eq 0 ]; then
promptYESNO "$LINE\nDelete This entry" "n"
if [ "$YESNO" != "y" ]; then
echo $LINE >> $passwd_tmp
fi
else
# keep this user
echo $LINE >> $passwd_tmp
fi
done
# replace passwd file
mv -f $passwd_tmp $passwd_file
blaztoff- I was wondering why you chose to delete the entries from /etc/passwd manually, and not using something like 'rmuser', 'userdel', or whatever command pertains to your OS. Your current method is going to leave entries in /etc/shadow, as well as user's home directories.
Not picking on your methodology- I know each site has unique requirements, just curious.
Not picking on your methodology- I know each site has unique requirements, just curious.
ASKER
It is a partial solution as I actually had to sue grep and I figured it out. Butt you put me on the correct path
ASKER
When I grep -v "$LINE" $TMP1 > $TMP1.new 2>/dev/null
this is outputting the full text of TMP1 and not everything but what its grep for I do not get it because I can do a grep -v string temp1 > temp1.new and it works. Any ideas what i am doing wrong?