Do something every X iteration in a bash loop

If you have a bash loop and want to ”do something” at every X iteration you are in trouble because bash isn’t that good with numbers. Anyway, today I created this small example that you can use. In my case I needed to read a pretty large txt-file and create a simple html output table of the rows. The problem was to insert TR-tags between the TD-tags like below:

td row 1
td row 2
td row 3
td row 4
td row 5
td row 6

My solution solved the problem! It is pretty helpful that we have the modulo (%) operator in bash.


# Change this to how many rows row you want to skip before doing something

for (( c=1; c<=100; c++ ))
	remainder=`expr $c % $doevery`
	echo "Remainder: $remainder"

	if [ $remainder = "0" ];	then
		echo "Every $doevery iteration"
		# Do something


Nagios check_nt over ssh-tunnel

I am a big fan of Nagios for host and service monitoring and this is my first post on the subject. My task was to check services on a Windows Server with Nagios and NSClient++. But the firewall only allowed me to use ssh and thats why I could not connect to port 12489 (that NSClient listens to) from my Nagios server. The only way to solve the problem was to use a SSH-tunnel that I can open and close whenever I needed to.

Workflow for my solution
1. Nagios initiates that a service should be checked.
2. Nagios executes the check_nt_by_ssh_tunnel check-command with additional parameters
3. The script creates a ssh-tunnel
4. The script checks the Windows server with the Nagios builtin command check_nt
5. The script returns the check_nt output
6. The script closes the ssh-tunnel
7. Nagios does its processing.

* A fully working Nagios installation
* NSClient installed and working on the Windows Server that should be monitored
* SSH autologin is configured between the two machines
* Read my other article for details about the SSH-tunnel used in this solution.

First you have to create the check-script on the Nagios server (in the Nagios libexec-folder). See below:


# $1 = HOSTNAME,
# $2 = LOCAL PORT, 14880
# $3 = USERNAME, ex: someusername
# $4 = CHECK PARAMETERS, ex: -w 80 -c 90 -v MEMUSE

if [ -z "$1" ]
        echo "Missing HOSTNAME"

if [ -z "$2" ]
        echo "Missing LOCAL PORT"

if [ -z "$3" ]
        echo "Missing USERNAME"

# Open ssh-tunnel and wait for it to open
ssh -f -N -L $2:localhost:12489 $3@$1 &
sleep 30

# Run check_nt command
CHECK="/usr/local/nagios/libexec/check_nt -H localhost -p $2 $4"
#echo $CHECK
eval $CHECK

# Close ssh-tunnel
sleep 5
CMD="ps -eo pid,args | grep 'ssh -f -N -L $2:localhost' | grep -v  'grep' | cut -c1-6"
#echo $CMD
PID=`eval $CMD` 
#echo $PID
kill -9 $PID

Make it executable:
chmod 755

Then verify that i works by running the command:
./ 14880 someusername ”-w 80 -c 90 -v MEMUSE”

You should then either see a valid Nagios plugin-output or get an error-message. Make sure that is works! You may have to modify the script depending on your *nix OS.

Next modify Nagios checkcommands.cfg or similiar and add the following. This makes the command available for use in Nagios.

# USAGE: check_nt_by_ssh_tunnel!11101!username!"-l 5,80,90 -v CPULOAD"
define command{
	command_name		check_nt_by_ssh_tunnel
	command_line		PATH_TO_COMMAND/ $HOSTADDRESS$ $ARG1$ $ARG2$ $ARG3$

Next add a service definition that uses the check-command.

define service{
	use				       generic-service
        host_name                        MY_HOSTNAME
        service_description             Memory usage
        check_command                 check_nt_by_ssh_tunnel!11100!username!"-w 80 -c 90 -v MEMUSE"

The last step you need to do is to restart Nagios and check if it works.

* I recommend you to change the portnumber for each service-definition to avoid collisions. Make them unique to the service-check.

Bash script that open and close an ssh-tunnel automagically

My problem was that I needed to connect to a port on a server that only was accessible by ssh. This connection should be made in a bash-script that starts and ends within a limited timeframe. That’s why I needed to solve the problem with a SSH-tunnel. George Notaras has made an article about auto-closing ssh tunnels that describes the problem and a solution that should work for most people. However, I did not need a auto-closing ssh tunnel because I want to close the tunnel whenever I want to.

My solution is a little bit more brute because it kills the tunnel. But hey, it works! Check out the simple solution below.

For this to work you need to have ssh auto login between the two servers.

I have used this solution successfully with the Nagios monitoring system. Read Nagios check_nt over ssh-tunnel.


# Open tunnel and wait for it to open
# 12489 = remote portnumber
# 3456  = local portnumber
# increase sleep-time if slow to connect
ssh -f -N -L 3456:localhost:12489 username@somehost &
sleep 30

# Run some command that uses the opened tunnel
# telnet localhost 3456

# Close the tunnel by killing it
sleep 5
CMD="ps -eo pid,args | grep 'ssh -f -N -L 3456:localhost' | grep -v  'grep' | cut -c1-6"
#echo $CMD
PID=`eval $CMD` 
#echo $PID
kill -9 $PID

You may have to change the parameters to the ps-command for this to work on your nix-machine.