bash

You are currently browsing articles tagged bash.

/bin/rm: Argument list too long

This isn’t really new, but it’s sure worth knowing… The fact that there’s a 128K buffer used to pass arguments to child processes in the Linux Kernel can have the following effect on shell external commands:

When you run commands such as rm spam* the shell (e.g. bash) will expand the “spam*” to a list of names of all files in the working directory that start with “spam”. That list is then passed to the executable /bin/rm using the 128K buffer mentioned above. If you have a large number of files, or the list gets long because of long file names, you may get an error message saying /bin/rm: Argument list too long.

To work around this you can get the list of filenames using find and pipe it to xargs which in turn invokes rm for every single file. There is no limit on the size of a pipe (or at least none that I am aware of for this practical purpose). Here’s the full command:

find . -name 'spam*' -print0 | xargs -0 rm

This differs from similar commands you might find in the -print0 and -0 arguments: These are needed in case you have spaces in your filenames.

For an in-depth explanation of both the 128K buffer and the spaces in filenames issue you may also want to read the May 2004 update in this blog post. (See, I told you it’s not really new.)

Since the upgrade to version 3.2.2 Nagios does not update the host alias macro when the configuration is reloaded. Macros are the variables used in commands, such as notification commands, i.e. the information you receive via E-mail when there is a problem with your hosts or services.

As long as you don’t change your host alias information you will never notice. I did change it and I found myself scratching my head for some time, especially since the same information does get updated in the web interface.

I found a greater number of forum discussions relating to this, but none seemed to offer a practical solution for larger scale environments.

After some pondering I came up with these lines:

service nagios stop
cp /usr/local/nagios/var/retention.dat /usr/local/nagios/var/retention.bak
grep -v ^alias /usr/local/nagios/var/retention.bak > /usr/local/nagios/var/retention.dat
service nagios start

They do the trick in my installations.

Update: Here’s a brief summary of the error and what the script does to work around it.

When Nagios parses the configuration and finds a new host it loads the alias field into memory. When Nagios reloads the configuration, the alias information that is already in memory does not get updated. When Nagios stops (or before reloading the configuration) the alias information in memory is dumped to the retention.dat file. When Nagios isn’t running and you start the service, it doesn’t load the alias information from the configuration files but from retention.dat, unless that information is not present in the file. So my solution does the following:

  1. Stop Nagios
  2. Make a backup copy of the retention.dat file (Note: I’m copying the file instead of renaming it to make sure that it will still have the same owner/group and permissions when I write to the original file in the next step)
  3. Strip all lines starting with “alias” from the backup file and overwrite the original retention.dat file with this data
  4. Start Nagios

You may have to tweak the file location for the retention.dat and backup files. You may also need to change the commands that stop and start the Nagios deamon.

Facebook Puzzles Submissions

Quite a few people have reported issues with submitting solutions to the Facebook Puzzle Master. I hated the idea of installing and configuring a MUA to make things work, so I wrote a bash script. This should work on any Unix/Linux server with Postfix or Sendmail that is otherwise capable of sending Internet E-mail.

So far I have not been using any compiled languages. The script will have to be edited to be able to send compressed submissions with a Makefile etc.

The script should be in the same directory as your executable file and you should have a folder named “.archived-submissions” to hold your sent items, or edit the script accordingly. Then just call $ ./submit.sh <keyword> e.g. $ ./submit.sh meepmeep

You must edit line 2 (FROMADDRESS) to hold the address linked to your Facebook account (Google Mail, Yahoo!, university accounts, etc.) and line3 (SENDERADDRESS) to hold an address regularly used for sending on your server (to make sure you make it around any spam filters). Both lines may be set to the same address, but this didn’t seem to work in my case with Facebook linked to my Google Mail address.

#!/bin/bash
FROMADDRESS="youraddress@gmail.com"
SENDERADDRESS="yourotheraddress"
SUBMITTO="1051962371@fb.com"

NOW=`date +%Y-%m-%d-%H-%M-%S`
BOUNDARY=_`date | md5sum | cut -d\  -f1`_

MSGFILENAME=.archived-submissions/$NOW-$1.msg

cat > $MSGFILENAME <<TFNAB-27-End-of-File
Content-Type: multipart/mixed;
        boundary="_001$BOUNDARY"
Sender: $SENDERADDRESS
From: $FROMADDRESS
To: $SUBMITTO
Subject: $1
Date: `date -R`
MIME-Version: 1.0

--_001$BOUNDARY
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

This text should be ignored by the robot

--_001$BOUNDARY
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="$1"

`base64 $1`

--_001$BOUNDARY--
TFNAB-27-End-of-File

/usr/sbin/sendmail -f $SENDERADDRESS $SUBMITTO < $MSGFILENAME

Note: it seems that using the address linked to your account is only of interest if you want to use the Facebook Puzzles App to post your successful submissions to your profile.