The OS or the shell define some useful character sequences which can improve your typing speed in the shell. For example the sequence ^W deletes the word on the left of the cursor. Or the character ^U is useful when inserting a password: you can press ^U once to delete the entire password instead of hitting backspace many times. If a character must be inserted "verbatim" in the shell (e.g. a TAB character), it can be prepeded by ^V. The following table lists some of the most useful character sequences:
| character | description | defined by |
|---|---|---|
| ^D | end of file (EOF) | POSIX.1 Terminal I/O |
| ^V | literal next (LNEXT) | POSIX.1 Terminal I/O |
| ^H | backspace one character (ERASE) | POSIX.1 Terminal I/O |
| ^U | erase line (KILL) | POSIX.1 Terminal I/O |
| ^W | backspace one word (WERASE) | POSIX.1 Terminal I/O |
| !xxx | find in history the command beginning with xxx | shell |
| ^R | find character sequence in history (completion mode) | GNU readline |
| ^G | escape from completion mode | GNU readline |
| ^A | go to the begin of the line | GNU readline |
| ^E | go to the end of the line | GNU readline |
The two following lines are equivalent on most shells (all POSIX shells):
sh$ foo=`echo bar`
sh$ foo=$(echo bar)
It is thus possible to use one or the other form equally though $() can be more easily nested. The only drawback of $() is that it is not accepted by some older shells (e.g. Bourne shell). Portable scripts should use backticks.
The two programs test and [ (UNIX allows many characters in filenames, even "[") are exactly the same. Sometimes the command [ is a link to test, with the difference that [ requires a "]" as last argument. It is a matter of taste whether to use one ore the other form. Be sure to put always a space between the closing bracket and the last argument to [, otherwise the closing bracket will not be separated from the last argument.
Simple calculations can be done with $(()). For example, i=$(($i+1)) increments i by 1. If integer arithmetic is not enough, bc or dc can be used. The following example prints the ration 1/3 with four digits precision.
sh$ echo 'scale=4; 1/3' | bc
The standard Unix tool awk can be used for more complex operations which contain loops, function calls, input parsing etc.
The following sed script prints a configuration file in a compact form on the screen, omitting blank lines and comments (beginning with #)
sh$ sed -e 's/#.*//; /^$/d'
You can use it as filter or by appending the filename at the end of the command.
This could be done with a combination of ps, sed and kill if there weren't already pgrep, pkill and killall doing this job.
The following example shows how to avoid printing "grep program" when calling ps (ps ax | grep program):
sh$ ps ax | grep [p]rogramm
Sometimes (especially in usenet) texts are 'encrypted' with rot-13. This means that the alphabet is rotated by 13 positions: "a" becomes a "n", "b" becomes "o" etc. The following command encrypts and decrypts texts with the rot-13 'algorithm':
sh$ tr "[a-zA-Z]" "[n-za-mN-ZA-M]"
The same program can be used to both encrypt and decrypt texts, because the English Alphabet contains 26 letters.
The man page of the bash documents some very useful (though widely unused) features in the chapter "Parameter Expansion". Some of the most interesting are:
sh$ x=camel
sh$ echo ${x}ot
camelot
sh$ file=track.mp3
sh$ echo ${file#track}
.mp3
sh$ file=track.mp3
sh$ echo ${file%.mp3}
track
sh$ file=track.mp3
sh$ echo ${file/.mp3/.ogg}
track.ogg
I've seen the following script in usenet (and naturally I've started it immediately...). It is equivalent to common Windows viruses, with the difference that the designed victim must paste the code into a shell... I assume as proven the fact that *nix is as well vulnerable as Windows by viruses; it is only more laborious to get infected.
sh$ :(){ :|:&};:
Once the program has been startet, it blocks the shell (in fact, it is a fork bomb). The script will be more readable if we write the function defined in the script not as ':', but, let's say, 'g':
sh$ g(){ g|g&};g
The script defines the function g, which calls itself in pipe with another instance of itself, and both processes are executed in the background (&). The last command in the script starts the desaster. Before you try to start the program, it would be better to limit the number of startable processes to a reasonable number by typing ulimit -u 50.