SED help (remove line::parse again::add line)

Aloha! I have just over 1k of users that have permissions that they shouldn't under our system. I need to parse a provided list of usernames, check their permissions file, and strip the permissions that they are not allowed to have. If upon the permissions strip they are left with no permissions, I need have a basic permissions line added to their permission file. I am creating this script so our helpdesk guys can use it later because I can see something similar happening again.

Everything on the following script works correctly unless the user has no permissions left. The sed statement will display the correct insertion but will not overwrite the file. I have also tried piping it to cat and then redirect to the file but that just appends....Please Help!! :confused:

Oh! BTW this is in Korn shell under AIX 5.3
Also FYI permission lines are always first in the file and they are the only lines that start with numerals.

echo "Where is the user Listing?"

read usrList

usrName=""

fChar=""

while [ 1 ]

do

  read usrName || break

      sudo sed -e '/APCLERK/d' /home/$usrName/.facet | cat >> /home/testdir/$usrName
  
      fChar=`head -c 1 /home/testdir/$usrName`

          if [[ $fChar != [0-9] ]]

          then

            sudo sed -f /home/testdir/sedInqIns.sed /home/testdir/$usrName > /home/testdir/$usrName

          fi                         

      


done < $usrList

Here is the sed insert file::

1,1{
 i\
1       /PRISM/SD-START "INQUIRY~      ; ; ; ;Y;   ;    ;0000;      ;    ;Y;      ; ;      ;     ~~"
 }

On execution of this script the users that have no permissions are left with a completely blank file (there should be other settings in the file besides permissions). The users that have other permissions are fine.

Any help will be greatly appreciated.
Mahalo!! :smiley:

I suspect the problem to be the following:

After changing the file /home/$usrName/.facet and writing the results to /home/testdir/$usrName (so far ok) you try to modify this file writing back to it immediately. This is FORBITTEN! Something like

sed 's/this/that' file > file.new

works, but

sed 's/this/that' file > file

won't. The reason is: sed will read the first line of the input file (which is "file"), apply any rules that might be applicable and then write the result (the changed or not changed line) to <stdout>. This <stdout> is at this moment pointing to "file" and this is why after the first line the file will contain nothing more than exactly that first line - so sed encounters the EOF and thinks it is finished. In the first example it is not writing back to its input file but some other file "file.new", which is why there is no problem.

There is another (perhaps minor) detail i found: You read from keyboard a variable "usrList" and do nothing with it. Why?

bakunin

just a minor bit of pedantry - usrList is being read via the '< usrList' statement at the end of the 'read.....' clause - or so it seems to me......???!

cheers

Sorry - I take that back - it doesn't seem to be being used at all. I should have kept my mouth shut!

Hi

I would have explained this behaviour somewhat differently: when the shell begins to process a command line, it will literally remove the characters that involve re-direction. In dealing with re-direction, the shell will "zero" a file that is being re-directed to. If there was data on the file, it will have been erased before the command is executed. The result is that the command -- in this case sed -- will never see any input, because it already has been destroyed. The first read will encounter EOF.

Most of us have fallen into this operational trap. For example, we often want to sort a file onto itself -- just re-ordering data, neither gaining or losing data. So sort has an option to write the output to the input file, but one must use "-o file", and not "> file". The GNU sed allows a similar construction with "in-place" editing, but what actually happens is that sed writes to a temporary file and then renames it at the end. You can see this if you display the inode number (ls -li file) before and after the operation. You'll see that they are different.

The flow-chart of shell operations is displayed in some books, for example, O'Reilly's Learning the bash shell, 2nd, page 177 ff ... cheers, drl

Believe it or not usrList actually feeds line by line into the do loop.

So, what I'm getting, is that in order for this to work correctly, I need to feed the intial sed statement to a temp file and then have the second sed use the temp back into the original? :smiley:

I changed the script to push to a temp file in the first sed, it works fine now.

Mahalo for all the help!!:b::b: