With a little side of applesauce...

Sunday, January 28, 2007

BASH - Pesky whitespace in string

I am moving my Exim virtual domain alias files from /etc/mail/virtual into LDAP, so was generating the LDIF from a file with the following syntax:

postmaster: someuser@localhost

webmaster: someuser@somedomain.com

The following for loop worked fine for the local users until I reached my Mailman domain:

for e in $(cat home | grep -v localhost); do u=$(echo “$e” | cut -d: -f1); email=$(echo “$e” | cut -d: -f2); cat mailalias.ldif | sed -e “s?USER?$u?; s?EMAIL?$email?; s?DOM?home?” ; done

The Mailman domain was in the following format, (BTW, I removed the whitespace in the files before using the for loop above):

allstaff:”|/var/lib/mailman/mail/mailman post allstaff”
allstaff-admin:”|/var/lib/mailman/mail/mailman admin allstaff”
allstaff-bounces:”|/var/lib/mailman/mail/mailman bounces allstaff”
allstaff-confirm:”|/var/lib/mailman/mail/mailman confirm allstaff”
allstaff-join:”|/var/lib/mailman/mail/mailman join allstaff”
allstaff-leave:”|/var/lib/mailman/mail/mailman leave allstaff”
allstaff-owner:”|/var/lib/mailman/mail/mailman owner allstaff”
allstaff-request:”|/var/lib/mailman/mail/mailman request allstaff”
allstaff-subscribe:”|/var/lib/mailman/mail/mailman subscribe allstaff”
allstaff-unsubscribe:”|/var/lib/mailman/mail/mailman unsubscribe allstaff”

The whitespace is important in the piped command to mailman, so I needed to leave it in the line. Therefore, the for loop was splitting the lines on the whitespace, and generating an ldif with the following mess, (note the mail attribute):
dn: mailAlias=allstaff-owner,dc=home,dc=com
objectClass: mailAlias
objectClass: domain
dc: home.com
mailAlias: allstaff-owner
mail: “|/var/lib/mailman/mail/mailman

dn: mailAlias=owner,dc=home,dc=com
objectClass: mailAlias
objectClass: domain
dc: home.com
mailAlias: owner
mail: owner

dn: mailAlias=allstaff,dc=home,dc=com
objectClass: mailAlias
objectClass: domain
dc: home.com
mailAlias: allstaff”
mail: allstaff”

I found this little tidbit:

http://tldp.org/LDP/abs/html/loops1.html

which tells you to quote your shell expansion:

for e in “$(cat home | grep -v localhost)”; do u=$(echo “$e” | cut -d: -f1); email=$(echo “$e” | cut -d: -f2); cat mailalias.ldif | sed -e “s?USER?$u?; s?EMAIL?$email?; s?DOM?home?” ; done

But, the problem still existed… Next, I found this great BASH FAQ:

http://wooledge.org/mywiki/BashFaq#head-7dfd029fd0b209ba25bb2659744e1f47734bde4c

which gives the following example for dealing with whitespace:

while read line
do
echo “$line”
done < "$file"

which was then translated into:

while read line
do
u=$(echo "$line" | cut -d: -f1)
email=$(echo "$line" | cut -d: -f2)
cat mailalias.ldif | sed -e "s?USER?$u? s?EMAIL?$email?; s?DOM?home?"
done < "home" > a.txt

Voila! Now we get:

dn: mailAlias=allstaff,dc=home,dc=com
objectClass: mailAlias
objectClass: domain
dc: home.com
mailAlias: allstaff
mail: |/var/lib/mailman/mail/mailman post allstaff

dn: mailAlias=allstaff-admin,dc=home,dc=com
objectClass: mailAlias
objectClass: domain
dc: home.com
mailAlias: allstaff-admin
mail: |/var/lib/mailman/mail/mailman admin allstaff

dn: mailAlias=allstaff-bounces,dc=home,dc=com
objectClass: mailAlias
objectClass: domain
dc: home.com
mailAlias: allstaff-bounces
mail: |/var/lib/mailman/mail/mailman bounces allstaff

NOTES:

Greg’s Wiki - BashPitfalls: http://wooledge.org/mywiki/BashPitfalls

mailalias.ldif:

dn: mailAlias=USER,dc=DOM,dc=com
objectClass: mailAlias
objectClass: domain
dc: DOM
mailAlias: USER
mail: EMAIL

No comments: