Shells

A shell is a program which stands between the user and the operating system. Its main purpose is to load and run other programs when requested. There are several shells available for Unix/Linux:

The modern shells, bash and zsh, basically started with sh and then added features of both tcsh and ksh as the authors saw fit, without breaking Bourne compatibility. (Similarly, Unix began with the Bell version (SysV). Berkeley Unix (BSD) made improvements and changes, and Linus Torvalds picked and chose what he liked the best to create Linux. In turn, some Linux features have fed back into BSD to create Apple’s OS-X.)

With only one (noted) exception, everything in the rest of this presentation applies to both bash and zsh. Most of the examples work with ash, too.

BASH

At minimum, bash or another shell provides a command prompt where a user types his or her intentions in the form of command lines. For example:

> cp -a file1 file2
>

where > is the prompt, cp is the command, -a is an option, and file1 and file2 are arguments.

The“command” can be external—a seperate program file to be run, internal—built into the shell for speed, a script— a series of commands stored in a file and executed by the shell as if typed in at the terminal, or a function—a script provided by the user as a part of the shell for speed. Any of these can be called via an easy-to-remember alias created by the user.

When necessary, a script can indicate on its first line which shell is to be used to execute the rest. If there is no explicit shell given, sh (or whatever is aliased to sh) is assumed. Here’s a simple example of a script:

> cat bin/unzipall

#!/bin/bash
# Loop to unzip all files given on the command line

for i in $@ 
do
  unzip $i
  echo $i
done

This script could have been typed in as a single line at the command prompt, using semicolons to separate the parts:

>for i in $@; do unzip $i; echo $i; done
The main advantage of the shell script is that it can be reused at will.

The two most important features of the shell’s language are loops, shown above, and tests, used to select alternatives. Here’s an example of a script with a test:

>cat bin/wdiff

#!/bin/bash
cd ~/words
if [[ -d /dell/words/ ]] 
  then diff -q --to-file=/dell/words/ ww.html nono.html 
  else echo "DELL not mounted" 
fi

Shell Variables

A shell variable can be set simply through the following:
> myvar=something
The value of a variable is used when the name is prefixed with a dollar sign:
> echo myvar   [prints myvar]
> echo $myvar  [prints something]

Within double quotes, values are substituted for shell variables. Within single quotes, they are not:

> echo "This is $myvar."   [prints This is something.]
> echo ’This is $myvar.’  [prints This is $myvar.]

Other Uses of Quotes

<>p> One major use of quotes on the command line is to allow blanks in an argument. For example,
> mycommand one two three
has three arguments, but
> mycommand "one two" three
has two. Either single or double quotes can be used for this purpose.

Another use is to prevent the shell from seeing characters that have special meaning. This sometimes works with double quotes and sometimes doesn’t— when in doubt, use single quotes, which always leave everything inside quotes “as is”. If quotes are not used, then special characters have to be “escaped” with a backslash to give them their actual meaning. For example:

> echo this;  [not this]   ***will not work
> echo ’this;  [not this]’  ***ok
> echo this\;\ \ \[not this\]   ***ok 
> echo this is an asterisk * and this isn’t  ***will not work
Quotes are often needed when a file name contains a space:
> cp myfile file two
> cp myfile file\ two
> cp myfile "file two"
> cd ’Program Files"

Shell Variable Substitution

Shell variables can be manipulated in various ways to get what you want. Here are a few examples:


> myfile="/home/dierdorf/myfile.ext"
> echo ${myfile}            prints /home/dierdorf/myfile.ext
> echo ${myfile#*/}         prints home/dierdorf/myfile.ext 
> echo ${myfile##*/}        prints myfile.ext
> echo ${myfile%.*}         prints /home/dierdorf/myfile
> echo echo ${myfile%%e*}   prints /hom
> echo ${${myfile%%.*}##*/} prints myfile
> echo ${myfile/my/your}    prints /home/dierdorf/yourfile.ext
> echo ${myfile//e/a}       prints /homa/diardorf/myfila.axt

Using Logic

In the expression

part1 && part2
part2 is executed only if part1 is true; otherwise it is skipped. (Logical AND)
part1 || part2
causes part2 to be executed only if part1 is false. (Logical OR)
! part1
is true if part1 is false, and vice versa. (Logical NOT)

Anything inside [[...]] is evaluated to be true or false. For example:


> cat bin/unhtmlall

#! /bin/bash
echo "================="
for i in "$@" 
do
    [[ -e "$i" ]] || continue
    cat "$i" | w3m -T text/html -dump >"${i%.htm*}.txt"
    dd="${i}_files"
    [[ -d "$dd" ]] && rm -r $dd
    dd="${i%.htm*}_files"
    [[ -d "$dd" ]] && rm -r $dd
    echo "$i --> ${i%.htm*}.txt"
done
rename s/\.txt\././ *.txt
echo "=================="
read -p "rm all converted files (yN) ==> " ANS
[[ $ANS == "y" ]] && rm "$@"

Command Line Helps

In addition to the fundamental job of running other programs on demand, modern shells all provide several other features for the user.

More, More, More

Most people customize their shell, selecting the prompt style they like, adding aliases, and setting options to change the default behavior. These customizations are normally in the file .bashrc (or .zshrc) in the user’s home directory. The number of settings is mind-boggling, and much too complex to go into here. If you want to change things, here are some sources:

Last modified: Tue Jul 13 17:59:58 CDT 2010