Handling arguments with spaces in bash

Way to often I get it wrong, so I decided to right this down…

When processing the list of arguments in your bash script, remember that often arguments such as file names contain spaces. The wrong way to go about this is:

#!/bin/bash
for FILE in $*
do
  echo "$FILE"
done

The right way to do it is:

#!/bin/bash
for FILE in "$@"
do
  echo "$FILE"
done

Advanced Bash-Scripting Guide explains the difference in “Internal Variables” chapter.

Reminder about NTP

NTP – Network Time Protocol allows for automatic and precise time synchronization over the network. There are many problems that can be caused by incorrect time – starting from logs confusions and going to software locks due to file timestamps. Configuring NTP is very easy. Just install the ntp RPM that comes with Red Hat or Fedora Linux (or a number of other Linux distributions) and use one of the two modes described below.

  1. Full blown NTP server. In this mode, you’ll have to edit /etc/ntp.conf to specify a number of NTP servers to synchronize time from, as well as a lit of machines that can synchronize time with your server. Usually you’d want to have only one full blown NTP servers per network.
  2. Simple NTP client. This is even easier to configure than the previous mode. All you have to do is add these two commands to your scheduler (cron or similar) to execute hourly.
    /usr/sbin/ntpdate -s ntp_server_ip_or_hostname
    /sbin/hwclock -w
    

While modern computers are very smart and fast, they don’t have any special skills at keeping the time precisely correct. Internal timers get offset by power cuts, CPU usage bursts, and things like that. The daily changes are small, but when left unattended for a longer period of times, clocks can run ahead or stay back for as long as days!

Here is a log record from one of the servers in our office:

21:01:01 ... ntpdate[...]:  ... offset 0.250427 sec
22:01:00 ... ntpdate[...]:  ... offset 0.251682 sec
23:01:01 ... ntpdate[...]:  ... offset 0.251269 sec
00:01:01 ... ntpdate[...]:  ... offset 0.251013 sec
01:01:01 ... ntpdate[...]:  ... offset 0.250451 sec
02:01:01 ... ntpdate[...]:  ... offset 0.250061 sec
03:01:01 ... ntpdate[...]:  ... offset 0.250239 sec
04:01:01 ... ntpdate[...]:  ... offset 0.250313 sec
05:01:00 ... ntpdate[...]:  ... offset 0.250112 sec
06:01:01 ... ntpdate[...]:  ... offset 0.250554 sec
07:01:01 ... ntpdate[...]:  ... offset 0.250691 sec
08:01:01 ... ntpdate[...]:  ... offset 0.249850 sec
09:01:01 ... ntpdate[...]:  ... offset 0.250418 sec
10:01:01 ... ntpdate[...]:  ... offset 0.250070 sec
11:01:01 ... ntpdate[...]:  ... offset 0.250488 sec

As you can see, this machine’s time inconsistencies are as large as quarter of a second per hour, which can result in 6 seconds per day (24 hours). This alone can cause noticable slowdowns in software that counts on time being always correct.

P.S.: There are NTP implementations for other operating systems as well. Google is your friend.

Finding all executable files on the system

find is one of the most useful and feature rich commands in Linux. Sometimes it is not that obvious which parameters should be fed to find for this or that behaviour. The manual could surely use some work.

Today I was trying to figure out how I can find all executable files on the system. The manual suggests that I use the -perm option with the specification of the mode. Figuring out the mode might get to you, so here is the example:

find / -type f -perm +0111

One could specify any mode what-so-ever. Just remember that 1 stands for ‘execute’, 2 stands for ‘write’, and 4 stands for ‘read’.

Bash prompts

Normal user promptroot promptToday I once again did something really stupid while being logged in as root. I already had my root and normal user bash prompts colored differently, but it turns out that the difference was not obvious enough. So, I decided to recolor the prompts a little bit more vividly.

It took me few minutes to refresh my memory with Bash Prompt HOWTO. After that I came up with this snippet in .bashrc of the normal user (left screenshot):

# Cyan on blue time and Yellow on blue user@host dir
export PS1="\n\[\033[44;1;36m\][\$(date +%H:%M)]\[\033[44;1;33m\][\u@\h \W]\[\033[0m\]$ "
export PS2="\[\033[44;1;36m\][\$(date +%H:%M)]\[\033[44;1;33m\][\u@\h \W]\[\033[0m\]> "

Root’s prompt (right screenshot) was a bliss after that:

# Cyan on red time and yellow on red username@host dir
export PS1="\n\[\033[41;1;36m\][\$(date +%H:%M)]\[\033[41;1;33m\][\u@\h \W]\[\033[0m\]# "
export PS2="\[\033[41;1;36m\][\$(date +%H:%M)]\[\033[41;1;33m\][\u@\h \W]\[\033[0m\]> "