The while-read loop controversy…

For about as long as I’ve been able to spell “bash”, I’ve seen the debates on the ‘Net about the proper way to use the shell to loop through a text file line-by-line (rather than item-by-item).

Of the small handful of common methods, it often comes down to this:

Using Cat
With this method, you call cat to pipe the contents of the file into the while loop.

cat $inputFile | while read loopLine
do
  (some stuff)
done

Using Redirection
With this method, you are redirecting the file into the loop, as indicated by the redirection arrow to the done statement in last line.

while read loopLine
do
  (some stuff)
done < $inputFile

So Which Way?
Once you talk the purists down off the ledge about you not using the IFS variable, and they get over the fact that you aren’t awk in the first place, you can move on to the discussion regarding which while read approach you’ll use; since most people do it that way anyway, and it’s easier to understand.  There.  I said it.

Between the two methods I describe above, it’s often said that the cat method is “wasteful”, but easier to understand for the person who comes after you. This is apparently because you see right away — as you read through the code in order — the thing that is getting passed into the loop, rather than having wonder or look for it.

Conversely, the redirected method is much more efficient (since you aren’t executing cat), but someone might not easily understand how it’s happening since they have to scroll down to see the input file , or may not understand what is being looped.

Both points are kinda’ true.  But when it comes down to it, the redirected method is just not that hard to understand, and I almost always use  it…

Sometimes, Joel…
…except in on situation, which is why I write this post; and this is almost always never mentioned in the argue-posts I read on this:  What if you need to manipulate the content *before* is gets parsed by the while read loop?  For instance, backslashes in the line, newlines in the wrong place, etc., read in from a group of files.

Take this example; I have a few files with a path in one of the fields that is to be parsed, like this:

servername volumename folder1\folder2

…and I want to read in the contents of all the few files into the one loop with an ls and a wildcard.

Using the standard redirection method in this case, the backslash is interpreted as an “escape”, and is parsed and dropped.  Since it’s a filesystem path, I obviously need that backslash; so the way I solved this situation was to use cat, and for each time I encountered the backslash, pass it to sed to add a second backslash as an escape before it gets parsed by the shell while read loop.

Here’s how I did that:

for inputfile in `ls $fewFiles`
do
  cat $inputfile | sed -e s/'\\'/'\\\\'/g | while read loopLine
  do
    # Then I grab the foldername from the short parent path
    item=`echo $line |awk -F '\' '{ print $2 }'`
    (some stuff)
  done
done

Of course, you notice that the backslash even has to be escaped in the sed command, as with the double-backslash that I use to replace it…

I know, I know what you’re thinking…  Just use Perl…
;)

While I’m at it… (Other Opensuse/Postfix Clean-up Items)

Following up my last post, “X11Forwarding Fails on Opensuse 12.1 with IPv6 Disabled“, there are a couple postfix items that seem to need to be cleaned up on all my servers.

IPv4-Only

If you get this error:

Apr 10 18:35:53 tools postfix/sendmail[23696]: fatal: parameter inet_interfaces: no local interface found for ::1

It’s because it’s searching for the IPv6 interface to run on.  Again, this is only because I like to disable IPv6 (as explained in the post referenced above).  As a result, you need to stop Postfix from trying to run on “ALL” protocols, and specify good ol’ IPv4.  Just vi /etc/postfix/main.cf and change inet_protocols = all to inet_protocols = ipv4 and rcpostfix restart.

Permissions Goofiness

Not sure why, but the permissions are goofed up on all my Opensuse 12.1 servers.  If you get these errors:

Apr 10 18:39:46 tools postfix/postfix-script[23808]: warning: not owned by group maildrop: /usr/sbin/postqueue
Apr 10 18:39:46 tools postfix/postfix-script[23809]: warning: not owned by group maildrop: /usr/sbin/postdrop

This just seems to have been buggy out of the box, or perhaps I did something wrong on all my installations….  Not a big deal for me at least (though I’ve read some others have had some struggles), this was an easy fix; I just ran /usr/sbin/postfix set-permissions and it cleaned it all up.  Another quick restart and I’m in business…

I hope that helps!

8)

X11Forwarding Fails on Opensuse 12.1 with IPv6 Disabled

I’m one of those people that still disables IPv6 on all my Linux boxes. And, I guess I’m being punished for it, since if you disable IPv6 on Opensuse, then X11Forwarding will no longer function in its default form.

The good news is that it’s an easy fix.  All you have to do is to force sshd to listen purely on IPV4.  So, just do the following:

vi /etc/ssh/sshd_config

(or gedit /etc/ssh/sshd_config, or kedit /etc/ssh/sshd_config)

…and change this block from:

#Port 22
#AddressFamily any
#ListenAddress 0.0.0.0
#ListenAddress ::

…to…

Port 22
AddressFamily inet
ListenAddress 0.0.0.0
#ListenAddress ::

With this change, the inet statement causes it to use IPv4 only, the 0.0.0.0 means listen on any valid IPv4 address (change to suit), and the Port command specifies the IPv4 port, usually changed to taste.

Enjoy!

iFolder 3.8 on Opensuse 12.1 (or 11.4)

It looks like some people are working very hard out there to try and preserve iFolder for future versions of Opensuse.  To those people (the NoFolder crew, Ravi Kumar, etc.), I’m indebted; I simply would be at a loss without iFolder.  Yes, I use DropBox, and a couple other things, but there’s just nothing like iFolder for complete control over the server and the sync’d content.

But the sad fact is, it has suffered a bit of neglect as of late.  Okay, a LOT of neglect.  And you’re probably here because you have an Opensuse 12.1 (or 11.4) server, and you tried to install iFolder 3.8.x on it, and had some trouble.

Notes: I strongly recommend you see my old post about setting up iFolder 3.8 on Opensuse 11.1 for background and additional detail, as this post will be brief and to-the-point without much supporting detail.  All the work in this doc was performed on the x86_64 version of Opensuse, and was tested on both 12.1 and 11.4.

First, build up an Opensuse 12.1 box.  I tend to build them with “Minimum X Window”, “IPv6 Disabled”, “SSH enabled”, and a dedicated partition for iFolder database and content (like /ifolder); other then that, fairly typical.  And I never install patches during installation.  So updates are the first thing we do after completion:

zypper ref; zypper up

So first, decide on a single name that you will use for the server for the host configuration, certificate creation, Apache2 configuration, and iFolder service configuration; it is imperative that you use one name!  For the following examples, I use “ifolder.yourLinuxGuy.com“.  Let’s configure that critical name and static address:

yast lan
vi /etc/hosts

Now, let’s install all the supporting software we need (of course findutils isn’t needed for iFolder, but I can’t live without it; but mono-wcf is the one most people seem to miss):

zypper in apache2-worker findutils-locate apache2-mod_mono log4net mono-core mono-data mono-data-sqlite mono-web mono-winforms mono-wcf xsp libflaim

Next we configure apache2 and related components, starting by generating a certificate (obviously, replace the values to suit):

/usr/bin/gensslcert -c US -s MI -l "City" -o "Your Linux Guy" -e email@yourLinuxGuy.com -d -n ifolder.YourLinuxGuy.com

Add SSL to the APACHE_SERVER_FLAGS section:

vi /etc/sysconfig/apache2

Un-comment and change “ServerName” to match the name you put in /etc/hosts, and optionally set “ServerAdmin” to your email address:

cd /etc/apache2/vhosts.d/; cp vhost-ssl.template vhost-ssl.conf; vi vhost-ssl.conf

Now to open ports 80 and 443, set FW_SERVICES_EXT_TCP="80 443":

vi /etc/sysconfig/SuSEfirewall2

Next, we install the stars of the show, the iFolder packages:

rpm -Uvh http://download.opensuse.org/repositories/home:/rkumar1:/branches:/network:/ifolder:/server_stable/openSUSE_11.4/x86_64/ifolder3-enterprise-3.8.4.0.11091.1-6.2.x86_64.rpm
rpm -Uvh http://download.opensuse.org/repositories/home:/rkumar1:/branches:/network:/ifolder:/server_stable/openSUSE_11.4/x86_64/novell-ifolder-enterprise-plugins-3.8.4.10192.1-6.3.x86_64.rpm

Update: Reader Mike informs me that these links above are no longer in service. In the interim, here’s an alternate download location:

rpm -Uvh http://yourlinuxguy.com/wp-content/uploads/2012/03/ifolder3-enterprise-3.8.4.0.11091.1-6.2.x86_64.rpm
rpm -Uvh http://yourlinuxguy.com/wp-content/uploads/2012/03/novell-ifolder-enterprise-plugins-3.8.4.10192.1-6.3.x86_64.rpm

And run all 3 configuration scripts (remember, see my older post for reference and detail, and please note I use an alternative simias datastore location of /ifolder):

simias-server-setup
ifolder-admin-setup
ifolder-web-setup

A note about the next step: If you just stopped here, you’d be able to pull up the /admin page, but not log in; you’d get a red message saying that your password doesn’t match or whatever.  I see this error quite commonly out there…  So let’s change the FlaimWrapper softlink pointer to an existing location:

rm /usr/lib64/simias/web/bin/FlaimWrapper.so
ln -s /usr/lib64/libFlaimWrapper.so.0 /usr/lib64/simias/web/bin/FlaimWrapper.so

Let’s make sure Apache2 comes up at each boot:

chkconfig apache2 on

And lastly, restart stuff:

rcSuSEfirewall2 restart;rcapache2 stop; rcapache2 start

And that should do it!  Log in at /admin, configure some users, etc., etc., etc.  I’m guessing you are here because you know already how to *use* iFolder, just got stuck installing and configuring it, so I’ll not go into any usage detail.

By the way, the NoFolder.com page has some good troubleshooting tips, but if you follow these steps accurately, and you use the SAME hostname throughout the configuration, you should be fine.

See, it’s not that bad.  And it’s totally worth it.  Enjoy!
;)

Using the shell to transform an Exchange email list…

Recently, I needed to create a one-address-per-line email address list, using only an existing Exchange group mailbox as input.

First we start in Windows…

I opened Outlook and prepared to create a new email and typed in the email group.  Once shown, I clicked the “plus” (+) symbol next to the group to expand it.  Swipe across the list, and do a CTRL+C to copy them to the clipboard.

Now, to Linux…

Shell into a Linux box, and paste the clipboard contents into a file (for instance, input.txt).  The input format will look a bit like this:

Jeremy Pavlov <Jeremy.Pavlov@YourLinuxGuy.com>
Other Guy <Other.Guy@YourLinuxGuy.com>

…and so on…

Now run the following command against your input file:

cat input.txt |tr ";" "\n" |awk '{ print $3 }' | sed s/"<"//g |sed s/">"//g

And you should end up with an output.txt that looks like this:

Jeremy.Pavlov@YourLinuxGuy.com
Other.Guy@YourLinuxGuy.com

…and so on.

This format is now perfect for use in various places, like… oh… for instance… the Subscribe2 plugin in WordPress… …Which is exactly where I use it to keep my internal subscriber list up-to-date.

Enjoy!

:)

 

 

Bash Ping Test for Domain Controllers

DNS can be a funny and unpredictable beast.

It is paramount that the DNS environment be stable and standardized in large environments, as well as small.  But in large environments particularly, you run into some weird happenings…  Like for instance, where an Active Directory exists separately from the DNS environment, the DNS world can sometimes get out of sync without all the AD controls.

So if you have an environment where you cannot be certain that all the “A” records for your parent domain are properly registered and represented, you might want to regularly check up on the domain’s records with a script.  I’ve tossed together a fairly simple script that prompts you for the parent domain name, an IP address of a reliable DNS server, and then it goes out and makes sure that all the hosts listed as “A” records for the parent domain are actually *up* and responding to ping…

Just copy/paste the following into a file, and chmod +x the file, and then run it.  Enjoy!

#!/bin/bash

echo "What is the domain name to check? (like example.com): "
read DOMNAME
echo ""
echo "What is an authoritative DNS server for that domain? (like 10.1.2.3): "
read AUTHDNS

for item in `nslookup $DOMNAME - $AUTHDNS| grep "Address:"| awk '{ print $2 }'|grep -v "#53"`; do echo "Checking $item... ";ping -q -c 2 $item > /tmp/lastitem.txt; temp="$?";if [ "$temp" == "1" ]; then echo $item is unreachable;fi; done

echo "...Done!"

I hope that helps someone out there…
:)

WordPress Visual Editor Tab Disappeared… Again…

This is a common problem for many folks around the Internet.  You do some sort of an upgrade in WordPress, and you lose your “Visual” tab in the editing page, or you lose your buttons, etc.; all you have left is the “HTML” editing option.

This seems to happen to me every once in a while when I do upgrades, too.  And it happened to me again today, while upgrading to 3.3.1.

And, like you, I do the fresh replacement of wp-admin and wp-includes, and it doesn’t do any good.  I check the error logs.  I check other browsers and versions.  I clear caches.  I do a few other things that I find in the WordPress blogs.  All to no avail.

Well, I’m here to remind you AND MYSELF that next time this happen, just restart Apache first (of course this might only apply to those that have the luxury of a self-hosted site).  If that doesn’t work, (and it probably will), *then* do all those other things.

;)

 

Happy New Year, 2012!!

It’s been a wild year for Your Linux Guy.  My world has changed, and I’m busier than I ever have been before.  But I’ll do my best to keep bringing mildly interesting, odd, geeky, Linux-based posts to you in 2012.

I want to thank you all for reading my blog; and more importantly, for those who contribute (comments, post topic suggestions etc.).

Thanks!

Here are some neat year-end stats about the blog for your entertainment…  These are the posts that got the most views in 2011:

Thanks again!  And Happy New Year!

:)

Opensuse 12.1 Arrives…

I just couldn’t help myself!  I had to post this…

 

WordPress Jetpack On An Older Linux Server

Unless you are a regular reader to this blog and were here anyway, I’m guessing you stumbled on it from a search because youre having a problem with the Jetpack plugin for WordPress.  Well, well, well.  Recently, I also forced myself to install the Jetpack plugin;  and as the old saying goes, “…if it were easy to do, it wouldn’t be worth doing.”

Anyway, after installing and enabling Jetpack, I got the error that is apparently quite well-known among the WordPress user community:

Jetpack could not contact WordPress.com: register_http_request_failed. This usually means something is incorrectly configured on your web host.

And like you, I did the requisite amount of Googling; I found a few things, tried a few things, and none of them fixed my problem.  However, once I stumbled on this WordPress Support Forum thread, I realized I might be on to something when I read the post from member “houldsworth1″ describing the disabling of SSL if “…your web server is incapable of sending outgoing requests over HTTPS (as opposed to HTTP).”

After thinking about it for a moment, I thought, “Hey, I bet my server is just old enough that this would be a problem for me, too.”  So I attempted the suggested fix and found that the changes recommended by houldsworth1 need a little massaging in order to work with the latest version.  It turns out that instead of just editing line 1290 in the older version, you now have to edit a couple lines (because the developers have put in some extra courtesy checks to help you).

To start out with, like houldsworth1 recommends, the file to edit is:

<WP-ROOT>\wp-content\plugins\jetpack\jetpack.php

…but instead of the exact recommended change, on line 1422 change add the “false &&” to make it look like this:

if ( false && $jetpack->use_ssl[$method] ) {

…and on line 1427, do the same to make it look like this:

if ( false && wp_http_supports( 'ssl' ) ) {

And presto!  Communication, and the setup completed.  It worked for me!

Now here’s a caveat or two:  you aren’t *supposed* to have to do this.  If you need to do this, it probably means your webserver is too old (or has something else wrong) and should be replaced.  Because after you implement this, the Jetpack plugin is calling home over an unsecured channel (non-ssl).