Showing posts with label Shell. Show all posts
Showing posts with label Shell. Show all posts

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 id_rsa.pub. 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 id_rsa.pub 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 id_rsa.pub.

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

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

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.

Wednesday, 6 June 2007

Shell scripts

The following script is not an example of great programming, but shows some of the standard commands available in the UNIX shell:

l=1
for FILE in *.gif
do if test $l -ge 100
then mv $FILE $l.gif
elif test $l -ge 10
then mv $FILE 0$l.gif
else mv $FILE 00$l.gif
fi
l=$((l+1))
done

A standard loop can be programmed via

for (( n=1 ; n<9 ; n=$((n+1)) )); do echo $n; done

Using the shell

Never underestimate the power of the UNIX shell! The following one-liner converts a batch of files from gif to jpeg for you

for file in *.gif; do convert ${file} ${file%gif}png; done

Note that the %gif removes gif from the file name for you. If you are trying to create such a one-liner it is very convenient to use echo to first print commands before actually executing them, so

for file in *.gif; do echo convert ${file} ${file%gif}png; done

is harmless but gives you an indication of what will happen.