Programming

BASH assigning command output into an array

Often find myself needing to do this but never remember how…

# flirble=(`ls -ltr ssh* | tail -3 | tr -s ' ' | cut -d ' ' -f 9` )
# echo ${flirble[*]}
ssh_host_key ssh_host_dsa_key.pub ssh_host_dsa_key
# echo ${flirble[0]}
ssh_host_key
# echo ${flirble[1]}
ssh_host_dsa_key.pub
# echo ${flirble[2]}
ssh_host_dsa_key
# echo ${flirble[3]}

# ls -ltr ssh* | tail -3
-rw-------  1 robin cm-users 539 Aug 11 12:40 ssh_host_key
-rw-r--r--  1 robin cm-users 614 Aug 11 12:40 ssh_host_dsa_key.pub
-rw-------  1 robin cm-users 668 Aug 11 12:40 ssh_host_dsa_key

This and more useful array manipulation can be found in Chapter 26 of the Advanced Bash Scripting Guide.

Sed regular expressions

The sed regular expressions are essentially the same as the grep regular expressions. They are summarized below.

^ matches the beginning of the line
$ matches the end of the line
. Matches any single character
(character)* match arbitrarily many occurences of (character)
(character)? Match 0 or 1 instance of (character)
[abcdef] Match any character enclosed in [] (in this instance, a b c d e or f)
ranges of characters such as [a-z] are permitted. The behaviour
of this deserves more description. See the page on grep
for more details about the syntax of lists.
[^abcdef] Match any character NOT enclosed in [] (in this instance, any character other than a b c d e or f)
(character)\{m,n\} Match m-n repetitions of (character)
(character)\{m,\} Match m or more repetitions of (character)
(character)\{,n\} Match n or less (possibly 0) repetitions of (character)
(character)\{n\} Match exactly n repetitions of (character)
\(expression\) Group operator.
\n Backreference – matches nth group
expression1\|expression2 Matches expression1 or expression 2. Works with GNU sed, but this feature might not work with other forms of sed.

Perl goodies

Found these two nice links this morning, first a very nice periodic table of perl operators and second, a useful little cgi that helps find out what is installed on your server.

Setting a variable in bash if it is not defined

Update: An anonymous commenter pointed out that bash has the ability to do this in a much shorter way:

BLAH=${BLAH:-no}

Job done!, my original older way is below…

[root@sn-b02 init.d]# echo $BLAH

[root@sn-b02 init.d]# [ "${BLAH}" = "" ] && export BLAH="no"
[root@sn-b02 init.d]# echo $BLAH
no
[root@sn-b02 init.d]#

return codes

When running a command in bash it will store the return code in the special variable $?, like this:

[robin@book robin]$ ls -ld tmp
drwxr-xr-x  3 robin  robin  1024 Aug  3 11:02 tmp
[robin@book robin]$ echo $?
0
[robin@book robin]$ ls -ld bob
ls: bob: No such file or directory
[robin@book robin]$ echo $?
1
[robin@book robin]$

When running a series of commands in a pipe however it is sometimes necerssary to find the return code of an individual command in the pipe, in this case bash stores the return codes in an array names $PIPESTATUS which you can access like any other bash array. The array can only be used once however, so if you want to use it more than once store it in some other temporary array.

[robin@book robin]$ echo "tmp"  | xargs ls -ld
drwxr-xr-x  3 robin  robin  1024 Aug  3 11:02 tmp
[robin@book robin]$ echo ${PIPESTATUS[@]}
0 0
[robin@book robin]$ echo "bob"  | xargs ls -ld
ls: bob: No such file or directory
[robin@book robin]$ echo ${PIPESTATUS[@]}
0 1
[robin@book robin]$ echo "bob"  | xargs ls -ld
ls: bob: No such file or directory
[robin@book robin]$ echo ${PIPESTATUS[1]}
1
[robin@book robin]$

Perl timeouts

Some perl that sets a timeout value

#!/usr/bin/perl

$SIG{ALRM} = sub { alarmed(); };

alarm(20);
eval { check_whatever; };
alarm(0);

sub check_whatever()
{
  # stuff to do that might timeout
  exit 0;
}

sub alarmed()
{
  # stuff to do after the alarm has gone off.
  exit 1;
}

Thanks to Timbo for help with this…

CSS Column layout examples

Nice examples of multi column css layout here