LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Server
User Name
Password
Linux - Server This forum is for the discussion of Linux Software used in a server related context.

Notices


Reply
  Search this Thread
Old 03-25-2009, 12:39 PM   #1
zokken
Member
 
Registered: Oct 2008
Posts: 44

Rep: Reputation: 16
Bash Script Help


Hi,

I wrote a simple script to determine which of our users are forwarding their email and to what address, so that we can grab statistics about the usage of our mail system. The script works but I know it's not very efficient, so I'm just looking for some tips on how to improve it (which would also give me ideas for future scripts I write).

First let me explain a little bit about our mail system so the script makes sense.

- Non-system users are located in either /home/facstaff/ or /home/students/

- Each user is supposed to have a preferences file (though unfortunately, not everyone does), which stores the forwarding address (if there is one).

- If a user is forwarding, their preferences file contains the following line:

Code:
forward_addy=forwarding@address.com
- If a user is not forwarding, the same line should exist (although sometimes it doesn't) with no forwarding address. So:

Code:
forward_addy=
The script I wrote returns the username, whether they're facstaff or student, and either the forwarding address or 'none' if they're not forwarding. If anyone have any suggestions on how to improve it, let me know. I pasted it twice -- one without comments (in case that's easier to go through), and one with comments.


---

Code:
stdlist=`grep "home\/students" /etc/passwd | cut -f1 -d":"`
fslist=`grep "home\/facstaff" /etc/passwd | cut -f1 -d":"`
userlist=`echo $stdlist $fslist`

for i in $userlist; do
   echo -n "$i  "
   if grep "^$i" /etc/passwd | grep "home\/students" > /dev/null; then
      echo -n "student  "
   else
      echo -n "facstaff "
   fi
   if [ -f /usr/local/mail/$i.pref ]; then
      if grep forward_addy /usr/local/mail/$i.pref | grep -v "forward_addy=$" > /dev/null; then
         grep forward_addy /usr/local/mail/$i.pref | cut -f2 -d"="
      else
         echo none
      fi
   else
      echo none
   fi
done
---

Code:
# we want to eliminate all users who are not in /home/students/ or /home/facstaff/
# first we grab everyone in /home/students/
stdlist=`grep "home\/students" /etc/passwd | cut -f1 -d":"`

# next we grab everyone in /home/facstaff/
fslist=`grep "home\/facstaff" /etc/passwd | cut -f1 -d":"`

# now we add the two variables together to create a full list of users
userlist=`echo $stdlist $fslist`

# let's go through the entire list
for i in $userlist; do

# print the username
   echo -n "$i  "

# determine whether they're a student
   if grep "^$i" /etc/passwd | grep "home\/students" > /dev/null; then

# if so, state this
      echo -n "student  "

# otherwise, state that they're facstaff
   else
      echo -n "facstaff "
   fi

# make sure the user has a preferences file
   if [ -f /usr/local/mail/$i.pref ]; then

# if so, check if they're forwarding
      if grep forward_addy /usr/local/mail/$i.pref | grep -v "forward_addy=$" > /dev/null; then

# if they're forwarding, print the forwarding address
         grep forward_addy /usr/local/mail/$i.pref | cut -f2 -d"="

# if they're not forwrading, return 'none'
      else
         echo none
      fi

# if they don't have a preferences file, return 'none'
   else
      echo none
   fi
done
 
Old 03-25-2009, 03:53 PM   #2
jan61
Member
 
Registered: Jun 2008
Posts: 235

Rep: Reputation: 47
Moin,

here's another idea (not fully tested, I don't have such a configuration):

Code:
getent passwd | cut -f1,6 -d: | sed -rn '/:\/home\/(student|facstaff)$/{s#:/home/# #;p}' | \
while read user group; do
  forward_addy=
  test -f /usr/local/mail/${user}.pref &&
    forward_addy=`sed -rn '/^forward_addy=/{s/.*=//;p}' /usr/local/mail/${user}.pref`
  test -z "$forward_addy" && forward_addy=none
  echo "$user $group $forward_addy"
done
Goals:
- I try to minimize external program calls within the loop
- I try to prepare the data outside the loop

How does it work?
- the getent reads all lines from the passwd file
- the cut leaves only the necessary fields (user name and home directory)
- this output (user:/path/to/home) is the input for the sed
- the sed uses extended regex (-r) and is quiet by default (-n)
- only lines matching ":/home/facstaff" or ":/home/student" are processed
- for matching lines: replace ":/home/" with a blank, print the result
- the result is "user student" or "user facstaff"
- now feed a read loop, within the loop I can use $user and $group
- default $forward_addy to empty string
- if the prefs file exists: use one sed to get the "forward_addy" line and remove all but the part after "="
- if $forward_addy is empty: set to "none"
- now output the result

So I reduce the external calls to 3 outside the loop and one within each loop.

Jan
 
Old 03-26-2009, 08:36 AM   #3
zokken
Member
 
Registered: Oct 2008
Posts: 44

Original Poster
Rep: Reputation: 16
Interesting, thanks for the reply. I need to improve my sed skills.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
passing variable from bash to perl in a bash script quadmore Programming 6 02-21-2011 04:11 AM
[SOLVED] bash : getopts problem in bash script. angel115 Programming 2 03-02-2009 10:53 AM
Strange if statement behaviour when using bash/bash script freeindy Programming 7 08-04-2008 06:00 AM
Bash script to create bash script jag7720 Programming 10 09-10-2007 07:01 PM
[bash] having trouble debugging this bash script. jons Programming 4 02-08-2007 06:51 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Server

All times are GMT -5. The time now is 08:52 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration