Operating System - HP-UX
1752461 Members
5629 Online
108788 Solutions
New Discussion юеВ

Re: script formatting problem

 
SOLVED
Go to solution
Kevin (Gonzo) Bushman
Frequent Advisor

script formatting problem

O/S -> 11.11, PA-RISC

I've been working on a script for our security folks that will email a report listing all accounts within a certain set that were logged in to directly (versus su'ing to them).

If I run the command
last -R | grep | cut -c23-38,50-55

at the command line, I get this output:

workstation_A.abc 12:09
workstation_B.def 11:28
workstation_C.xyz 09:19

showing that the user I'm grepping for logged in from workstation A in the abc domain at 12:09, workstation B in the def domain at 11:28 and workstation C in the xyz domain at 09:19. That's all fine and good.

If I then put this command in a for loop, like this (for the purposes of looping through the set of accounts I need to check):

for i in `last -R | grep | cut -c23-38,50-55`
do
print $i (or echo, both results are the same)
done

I get this out put:

workstation_A.abc
12:09
workstation_B.def
11:28
workstation_C.xyz
09:19

Does anyone know why I'm getting different formatting from the same command? The only difference is that one is run at the command line straight out, the other is in a for loop (ksh).

TIA, I'll give points where needed.

-Gonzo

If you do nothing else in with your life, make friends with a dog.
10 REPLIES 10
TTr
Honored Contributor

Re: script formatting problem

Because "i" takes on the value of "workstation_A.abc" and "12:09" on different iteration of the "for" loop.

for i in "1 2 3 4 5"
do
print $i
done

will print
1
2
3
4
5
on separate lines. It does not matter that you have 3 lines, each line has two fields so you get 6 lines of output.

You need to grep your user login names from a different source. Also I don't see why you are grepping your users from the same list that you want to print.

Maybe something like

for i in
do
last -R | grep $i | cut -c23-38,50-55
done
Kevin (Gonzo) Bushman
Frequent Advisor

Re: script formatting problem

TTr,

I understand your point, and you are right. However, I looked at doing it the way you suggest. The problem is, if a given user has logged in multiple times, how do you format that output for the report I mentioned? That's why I was trying to handle it line by line, so I could format it for the report (for example, print "\t\t"). If I try to format what you you suggest or what I was trying, only the FIRST entry gets formatted, not any following entries. So I'm back where I started.

-Gonzo
If you do nothing else in with your life, make friends with a dog.
James R. Ferguson
Acclaimed Contributor

Re: script formatting problem

Hi:

TTr is correct, which leads to quoting:

for i in "$(last -R|grep |cut -c23-38,50-55)"
do
echo "${i}"
done

Regards!

...JRF...

Kevin (Gonzo) Bushman
Frequent Advisor

Re: script formatting problem

while this does keep the lines together, I still only get formatting on the first line returned, and hence my quandary from the start. That is,

for i in "$(last -R | grep | cut -c23-38,50-55)"
do
print "\t\t${i}"
done

(**I used print instead of echo to allow me to do some rudimentary formatting/spacing for the report.)

yields:

workstation-B.def 11:28
workstation-C.xyz 09:19

What I need to be able to do for the report is something like this:

workstation-A.abc 12:09
workstation-B.def 11:28
workstation-C.xyz 09:19


-Gonzo
If you do nothing else in with your life, make friends with a dog.
James R. Ferguson
Acclaimed Contributor
Solution

Re: script formatting problem

Hi (again):

> while this does keep the lines together, I still only get formatting on the first line returned, and hence my quandary from the start.

Try this:

last -R|grep root|cut -c23-38,50-55|while read LINE
do
print "\t\t${LINE}"
done

Regards!

...JRF...
Dennis Handly
Acclaimed Contributor

Re: script formatting problem

>last -R | grep | ...

You can also provide the user names directly on the last(1) command line:
last -R
Kevin (Gonzo) Bushman
Frequent Advisor

Re: script formatting problem

You can also provide the user names directly on the last(1) command line:
last -R

That's true, BUT, by doing the grep the way I had it eliminates the blank line and the "wtmp begins..." at the end of the report from the last command. (Hence the reason why I did the grep...)

Also, JRF's solution looks to be the ticket. I tried it manually and it worked. All I have to do now is put that in a larger loop to run through the accounts I need to check...

Actually, that is what I did manually. Tomorrow I will add this to my script and check to make sure it works. I've posted points where deserved and I will update tomorrow with the actual code I used in my script.

Thanks to all for your replies! They just prove that sometimes you need another pair of eyes and another brain to look at a problem before you can see the solution!

-Gonzo
If you do nothing else in with your life, make friends with a dog.
Dennis Handly
Acclaimed Contributor

Re: script formatting problem

>by doing the grep the way I had it eliminates the blank line and the "wtmp begins..." at the end of the report from the last command.

Performance wise, it is better to reduce the amount of data as close to the source as possible, otherwise you'll pass many megabytes in the pipe. If you don't want to figure out how to remove the last two lines, you can still leave your grep there:
last -R | grep -v -e "^$" -e "^WTMPS"
last -R | grep

(Though you'll probably need to add a comment why are using the second grep. ;-)
Kevin (Gonzo) Bushman
Frequent Advisor

Re: script formatting problem

Dennis - Touche!

Yeah, it only makes sense to run the last for the account in question to eliminate as much unneeded data as possible. Performance will be better that way. Then do a grep for the account again to also eliminate the blank line and the wtmp starts on line. That way you limit yourself to only the data you really are looking for.

So, what I ended up doing was something like this:

last -R $ACCT | grep "$ACCT " | cut -c23-38,50-55 | while read LINE
do
print "\t\t $LINE" >> $REPORT_FILE
done

This does keep the formatting on each and every line returned and prints it to the report file as it should so the data lines up in nice neat columns.

Thanks all for your help. Security is much happier with the new report.

Points given.

-Gonzo
If you do nothing else in with your life, make friends with a dog.