Link to home
Start Free TrialLog in
Avatar of blaztoff
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
 
}

Open in new window

Avatar of blaztoff
blaztoff

ASKER

I think I have figured out what my problem is but I do not know a solution.

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?
Avatar of woolmilkporc
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
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
ASKER CERTIFIED SOLUTION
Avatar of Tintin
Tintin

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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
>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.
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?
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

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
}

Open in new window

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/bin/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.
So this is not on a Linux system then?
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?
HP-UX
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

Open in new window

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.
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