Thursday, 1 November 2007

Passwordless ssh

It is very convenient to use ssh to login into different workstations or for instance our Beowulf cluster elegast without having to re-type your password all the time. It is possible to setup things in such a way that this is possible. Here's the howto.

First you need to generate a so-called RSA key. Type
ssh-keygen -t rsa

This will create two files: id_rsa and The first should be kept secret, the second is public. You should now login into the remote machine. If the file ~/.ssh/authorized_keys exists, append the contents from the file to it. If it does not exist, create the directory ~/.ssh (with permissions rwx for yourself and no permissions for group and others) and the file authorized_keys (with permissions rw- for yourself and r-- for group and others) with as its contents the file

You should now be able to do passwordless ssh logins.

Bash programming

The standard shell under Linux is called Bash (the GNU Bourne Again SHell). Even though people are generally used to do a lot of stuff using graphical user interfaces, the command prompt can be very convenient for some tasks. Here are a few simple examples of how to get things done using your keyboard rather than your mouse.

Command line use by example

To convert all .gif files in a directory to .jpg, type
for file in *.gif; do convert ${file} ${file%gif}png; done

To find all .tex files in a directory including the subdirectories, type
find . -name "*.tex"

To filter out those files that contain the word "dimension", use
grep dimension `find . -name "*.tex"`

The code between the backquotes (`) is evaluated first and the output it generated is listed as if you typed it at the end of the command. In Bash you can also use $(command) as an alternative to the backquotes, which has the benefit that it can be nested. For example to get the number of bytes of all tex-files that contain the word dimension, you can say
du -s -k $(grep -l dimension $(find . -name "*.tex"))

To make the search on "dimension" case insensitive, use
grep -i dimension `find . -name "*.tex"`

To count the number of occurences, use
grep -i dimension `find . -name "*.tex"` | wc -l

which might be written shorter - but less illustrative - as
grep -c -i dimension `find . -name "*.tex"`

I'm sure you can use these examples to do powerful text searches yourself.

To rename a bunch of .gif files in a directory to new names like 001.gif, 002.gif etc., you could type

for f in *.gif; do
mv $f $(printf '%03d' $l).gif

This example also shows how to use if statements. A simple for loop can be programmed as
for (( n = 1 ; n < 9 ; n++ )); do echo $n; done

Writing scripts

If you have many commands that you use more than once, you can also create a text file in your favourite editor, type #!/bin/bash as the first line, and then put some shell commands. If you save the file and make it executable with chmod (see below), you have written a shell script and can simply execute all command by typing the script's name. This is like creating a Matlab script versus typing commands in the Matlab command window. In bash scripts, you can use a couple of funny looking variable names that have special meaning:

Variable Meaning
$0 name of the script
$# number of arguments given on the command-line when calling the script
$1 first argument given to the script
$* all arguments
$@ all arguments
$$ PID of the script

The difference between $* and $@ is subtle. Usually the latter does what you think it will do, while the first one has a slightly different semantic meaning. If you say "$*" it will expand to the single string "$1$IFS$2$IFS$3...", where IFS is an environment variable that contains a space by default but might have another value, e.g. the character ':'. When you say "$@" it will expand to the list of strings "$1" "$2" "$3"..., which is usually what you mean.

Parentheses in mathematical formulas

If you use \left( and \right) in LaTeX, it will automatically scale the parentheses for you to match the size of whatever you put between them. Sometimes LaTeX doesn't do a good job though, and you'll have to help the program. Here's an overview of the commands you can use for creating parentheses in different sizes:

  • (, )
  • bigl(, bigr)
  • Bigl(, Bigr)
  • biggl(, biggr)
  • Biggl(, Biggr)