NILUG

Wednesday, 22 February, 2006

Introduction to Bash

Filed under: Uncategorized — nilug @ 12:58 pm
    I. Introduction

      a. What is Bash?
      b. Bash competitors

    II. Using Bash

      a. Editing the command line
      b. Controlling the command history
      c. Wildcards
      d. Aliases
      e. I/O redirection
      f. Pipelines
      g. Shell prompts
      h. The environment

    III. Bash Scripts

      a. Built-in commands
      b. External commands
      c. Shell programming

I. Introduction

I.a. What is Bash?

Bash (the Bourne Again SHell) is a command shell. It provides a way for the user to communicate to the Linux kernel, and for the kernel to communicate back to the user. When you enter something at the command prompt, that information is (usually) passed along to the kernel. The results are (usually) passed back to the Bash shell.

Like the MSDOS/Windows program command.com, Bash is a command-language interpreter. Unlike command.com, it is a very powerful program – one that provides enough power and utility to actually write program applications in.

The Bash shell has its own built-in interpretive programming language, which supports most of the programming constructs found in high-level languages, such as looping, functions, variables, and arrays. It has a set of built-in commands such as cd, echo and pwd. It can execute other programs, such as ps, find and grep.

I.b. Bash competitors

Unlike MSDOS/Windows command.com, there is more than one command shell in Linux competing for your affections. Bash is probably the most popular, and is the default for most Linux distributions. Other shells available include the C-shell (csh), the Bourne Shell (bsh) and the Korn Shell (ksh).

All of these shells have their strengths and weaknesses. Bash seems to be the most well-rounded of the shells, providing strong input and processing capabilities.

II.a. Editing the command line

When you enter commands at the Bash prompt, you may often use command line completion to help you with the command. Here's how it works. Let's say you are user mburton and you are in a directory that contains a file called 'myverylongbashtalk.txt'. You want to copy that file to a directory called '/home/mburton/work'. You start entering the copy command like this:

cp myv

At this point, you don't have to type the rest of the file name – you can use command line completion to do that. Simply hit the Tab key, and if the first three letters you typed start only one file, that file will be displayed on the command line:

cp myverylongbashtalk.txt

If more than one file starts with those letters, Bash will beep at you and you can type a few more letters and press tab again.

To complete the command, we can type out the long path to the directory, or we can use a shortcut. In Bash, the tilde (~) means 'user home directory', so we can type

cp myverylongbashtalk.txt ~/work

instead of

cp myverylongbashtalk.txt /home/mburton/work

All of this built-in Bash capability is designed to make your life a bit easier.

If you need to edit a command because you've forgotten something or you made a mistake, you can do that using the backspace, delete, left and right arrow keys. Remember that Bash is always in 'insert' mode so if you type something in the middle of the command line, everything to the right is moved over to make room for the insertion.

Here is a list of some of Bash's command line editing keys:

Key(s) Command
Tab Complete a file name if possible
Backspace Erase the character to the left of the cursor
Delete Erase the character under the cursor
Home, Ctrl-A Go to the start of the line
End, Ctrl-E Go to the end of the line
Left Arrow, Ctrl-B Go one character to the left (back)
Right Arrow, Ctrl-F Go one character to the right (forward)
Ctrl-K Delete from cursor to end of line
Ctrl-U Delete from cursor to start of line
Ctrl-W Delete one word to the left
Ctrl-Y Undelete what was just deleted
Ctrl-L Clear screen
Enter, Ctrl-M Execute the command line

Here is a list of how you can use the tilde as a shortcut:

Keys Command
~ Substitute the contents of $HOME in the line
~user Substitute the user's home directory
~+ Substitute $PWD (current directory)
~- Substitute $OLDPWD (last current directory)

II.b. Controlling the command history

The Bash command line maintains a limited history of the commands you have entered. It maintains a unique history for each user, so if you switch users using the 'su' command, you will have a different history to work with.

The Bash command history is provided to reduce the amount of work you have to do to create a command line. If you want to do the same or similar command repetitively, you can pick up the command by navigating through the command history, make your changes and execute the command. Executed commands will be added to the command history.

There are a couple of ways to navigate through the command history. The easiest method is to use the up arrow and down arrow keys to scroll in the history.

If your history is long and you want to pick up a particular command, try using Ctrl-R. You press the Ctrl-R key, then the first letter of the command you want. A command starting with that letter will be displayed. If it is not the correct command, press Ctrl-R again and the next command in the history that starts with that letter will be displayed. Keep pressing Ctrl-R until you find the command line you want.

Here is a summary of the command history keys:

Key(s) Command
Up arrow Display the command line previous to the current one
Down arrow Display the command line next from the current one
Ctrl-R (letter) Display the command line starting with (letter)
Page Up Go to the start of the history
Page Down Go to the end of the history

You can also access the command line history using two Bash commands. The 'history' command will display all lines of the history. If you add a number to the history command, it will display the latest number of lines to be displayed, i.e.,

history 5

will display the last 5 lines of history.

The other command that accesses the comand line history is the 'fc' command. fc allows you to read the history and put the results in an editor, where you can make changes to it. You can then use the history command to write the changed history to the actual history file.

II.c. Wildcards

Whenever you enter a command in Bash, you can use 'wildcards' in the command. A wildcard is a special character or characters that will match anything. Wildcard characters used by bash are the asterisk '*', the question mark '?' and square brackets. The asterisk will match zero or more characters. The question mark will match a single character. The square brackets will match a specific range of characters. For instance, suppose we are in a directory that contains the following files:

    file.txt
    file1.txt
    file2.txt
    file3.TXT
    txtfile

If we want to list all the files that start with the word 'file', we would enter

ls file*

The asterisk will match all the characters following the 'file' part, which will list all the files except 'txtfile'. If we want to list just the 'txtfile', we could enter

ls *file

If we want all the files that end in '.txt', we would enter

ls *.txt

Note that the 'file3.TXT' file would not match the above request, since its extension is in upper case.

If we want to list all files with 'file' in them, regardless of position in the name, we could enter

ls *file*

We can use the question mark to make more detailed matches. If we wanted all the files that have a number in them, we could use

ls file?.*

The first and last file would not be listed. We could also use square brackets instead of the question mark, and put the character range in that we need:

ls file[0-9].*
ls file[123].*

These will both match the same way as the question mark.

Special note: The MSDOS command.com shell also supports wildcard characters, but the two shells use them very differently. command.com passes along the wildcard to whatever command it is executing. It is up to that command to expand and use the wildcard character.

On the other hand, Bash expands the wildcard on the command line before passing along the command line to the command. This means that the command does not need to do any work to expand the wildcard. For example, in the above directory, if you wanted to list the files that ended in numbers using command.com, you would enter

dir file?.*

and it would pass the following to the dir built-in command

file?.*

In Bash, you would enter

ls file?.*

and it would pass the following to the ls built-in command

file1.txt file2.txt file3.TXT

II.d. Aliases

An alias is a short command that Bash can translate to another longer command. For instance, let's say that you prefer to use the 'ls' command with the '-la' flags. We can define an alias for that and call it 'dir':

alias dir="ls -la"

We can then use the 'dir' command in place of the 'ls -la' command.

You can also use alias to redefine existing commands. Many distributions do this. For instance, have you ever tried to remove files and have Bash ask you if you want to remove each and every file? The 'rm' command has been redefined like this:

alias rm="rm -i"

which puts it in interactive mode.

Any commands that are redefined have been done in the .bashrc script, which starts up when you start up a Bash shell. There is a .bashrc script for each user in their home directory.

II.e. I/O redirection

Redirection allows the user to change the source or destination of data being used by a Bash command.

Commands or programs sometimes get their input from the console and send their output to the console. The source of data from the console is a stream called 'stdin'. The destination for output is a stream called 'stdout' and the destination for error messages is a stream called 'stderr'. I/O redirection allows you to change these sources/destinations to be other streams. You can get input from a file and send output to another file or even to the null device. Here is a list of I/O redirection characters:

Keys Command
&>word send both stdout and stderr to 'word'
>&word send both stdout and stderr to 'word'
[n] use 'file' for input
[n]>file use 'file' for output
[n]>!file same as '>', but overrides noclobber.
[n]>>file same as '>', but append data if file exists
[n]<>file open file for read/write
[n]<&m duplicate input file descriptor from m
[n]>&m duplicate output file descriptor from m
[n]<&- close input file descriptor
[n]>&- close output file descriptor

These redirection characters can be used on the command line, or in a script. The [n] allows you to open multiple streams simultaneously.

Example: list directory contents to a file named 'home.ls'.

ls * >home.ls

Example: run the 'foo' command, getting the input from file 'input.foo' and sending the output and error messages to the null device.

foo /dev/null

or

foo /dev/null 2>&1

II.f. Pipelines

Pipes allow you to feed the output of one command or program into another command or program as its input. The pipe character (|) is used to string these multiple commands together.

Example: Look for the string 'net' in the current programs that are running.

ps -ef | grep net

The output from the 'ps' command is fed to the 'grep' command. It then looks for a match to the string 'net'. If it finds one, that line is displayed.

II.g. Shell prompts

When you are interactively using Bash, the program prompts you for input by displaying a prompt. It does this by printing the primary prompt string $PS1. Whatever is stored in that string is used as the bash prompt. The prompt string has its own special characters that can be used to display some very informative prompts. The special characters are

Keys Command
\\a the ASCII BEL character. Beeps at you.
\\d the date in Weekday Month Day format
\\e the ASCII escape character (octal 033)
\\h the hostname up to the first dot (.)
\\H the full hostname
\\n the ASCII newline character
\\r the ASCII carriage return character
\\s the name of the shell
\\t the time in 24-hour HH:MM:SS format
\\T the time in 12-hour HH:MM:SS format
\\u the user's username
\\v the version of the bash shell
\\V the version and patch level of the bash shell
\\w the full path of the current working directory
\\W the current working directory only
\\! the history number of this command
\\# the command number of this command
\\$ a '#' if the effective UID is 0, otherwise a '$'
\\@ the time in 12-hour am/pm format
\\\\ the backslash character
\\nnn the ASCII character corresponding to the octal number nnn
\\[ start a sequence of non-printing characters
\\] end a sequence of non-printing characters

You can use the escape character with VT-100 escape sequences to create colorful and useful command prompts.

II.h. The environment

Like the command.com shell in MSDOS, Bash maintains an environment for each instance of itself. The environment contains shell settings in the form of environment variables. We have already touched on several of these ($HOME, $PWD, $PS1, etc.). Whenever a program is executed, that program receives a
copy of the environment variables from the process which executes it.

You can display a list of the current environment by typing 'set'.

You can create new environment variables or change the values of old variables. To do this, simply type the name of the variable, an equals sign, and the value of the variable.

These environment variables have many uses. You can display them, test them or programs you are running can use them.

III. Bash Scripts

Bash has a built-in language you can use to create complex actions on your computer. When you put these actions in a file to be executed by Bash, it is called a 'shell script'. A shell script is basically a small program that is interpreted and executed by Bash.

III.a. Built-in Commands

Bash supports two kinds of commands – those that are built into the Bash shell, and those that are separate executable programs or scripts.

Here is a list of the commands that are built into Bash:

Command Description
source read and execute commands from a file
: null command returning 0 exit status
alias create an alias
bg put a job in the background
bind display/modify 'readline' function and key bindings
break exit from an enclosing for, while, until or select loop
builtin execute a builtin command and return status
cd change current directory
cd - change current directory to $OLDPWD
command execute a command with arguments
continue do next iteration of for, while, until or select loop
declare
typeset
set attributes and values of variables
dirs display the directory stack
disown remove jobs from the table of active jobs
echo display the rest of the line on the stdout device
enable enable/disable shell built-ins; load/unload new built-ins
eval evalute the rest of the line and execute the result
exec execute the rest of the line in place of the shell
exit exit from a shell script with a return value
export no args – print names and values of exported variables
with args – export variable to the environment
fc print range of history commands
fg put a job into the foreground
getopts parse parameters and options
hash no args – print the hash table contents
with args – add a name to the hash table
help print help for commands that match the supplied pattern
history print the command history
jobs list information about jobs
kill terminate the listed job
let evaluate an expression. Exit 0 if non-zero, 1 otherwise
local create variables local to the current function
logout exit a login shell
popd remove entries from the directory stack
printf print output like ANSI C printf
pushd add an entry to the directory stack
pwd print working directory name
read read stdin and assign values to a list of variables
readonly mark variables as read only
return exit a function with a return value
set no args – display the environment variables
with args – set flags and options
shift rename positional parameters
shopt print or change values of shell options
suspend suspend current shell until a SIGCONT is received
[
test
evaluate conditional expressions
times print accumulated process times
trap execute a command if a specific signal is received
type describe how the shell interprets a name
ulimit set or print per-process limits
umask set the creation permissions
unalias remove an alias
unset remove a variable
wait wait for a specific job.

III.b. External commands

All commands in a shell script that are not on the above list should be external commands. If you specify a complete directory path to the command, Bash will use that path. If you specify just the command, Bash will look in your $PATH list for the command.

III.c. Shell programming

By using a combination of the above built-in commands, external commands and Bash control commands, you can write shell scripts that will perform complex functions. The control commands allow you to control the script execution flow. Here is a list of control commands for Bash:

Command Description
! execute a pipeline
case..in..esac case statement for Bash
for..in..do..done for statement for Bash
func() {..} define a function
if..then..else..fi if statement for Bash
select..in..do..done menu statement for Bash
time execute a pipeline; print times on stderr
until..do..done until statement for Bash
while..do..done while statement for Bash
((..)) arithmetic evaluation
[[..]] expression evaluation
(..) execute the list in a sub-shell
{..} execute the list in the current shell

The best way to descirbe how these commands are used is with examples. Here is a small script that prints the numbers from 0 to 9:

#!/bin/bash
# Print numbers from 0 up to 9
for i in 0 1 2 3 4 5 6 7 8 9; do
echo $i
done

Note that the first line starts with a shebang (#!). This tells the shell which command interpreter to use to run the script. It could easily be perl or C shell instead of bash, but our script is a bash script.

The next line is a comment so we will remember what the script does.

Next is a program loop. The variable i is assigned each of the values in the list. When the list is exhausted, the loop ends. Inside the loop we echo the variable i to the console.

Here is another example which uses an 'if' statement:

#!/bin/bash
# Make a backup of the fstab file, if it exists
if [[ -e /etc/fstab ]]; then
cp /etc/fstab /etc/fstab.bakup
echo "fstab backed up."
else
echo "fstab does not exist."
fi

As a final example, here is how to process command line arguments:

#!/bin/bash
# Check for a cmd line arg and echo it
if (( $# > 0 )); then
echo "Command line argument: $1";
else
echo "No command line argument present"
fi

Note that the command line arguments are numbered $0, $1, $2, etc. The $0 argument contains the name of the script being run, so the first argument is $1. The $# variable contains the number of command line arguments.

This concludes the introduction to bash. If you want to learn more about the command shell, I suggest that you look for a tutorial on the Internet, or purchase "Learning the bash Shell", Second Edition By Cameron Newham and Bill Rosenblatt, published by O'Reilly.

Installing Linux Applications from Source

Filed under: Uncategorized — nilug @ 12:52 pm

Whether your Linux system uses apt-get or rpm to install new software, it is occasionally necessary to install a program or library from the source code.

Source code for programs is often packaged into archive 'tarballs'. These tarballs have file names that end in tar.gz, tgz, .gz or .bz2. These archives contain the actual source code and instructions on how to compile and install the program.

Here are the steps you need to install such programs on your Linux system. They are meant to be typed into a terminal session.

1. Copy or save the program archive file someplace in your home directory. I have a subdirectory in my home directory called Downloads where I usually store these files.

2. Unpack the file. For instance, if you have a program archive file called lame-3.96.1.tar.gz, then you can unpack it with

tar xvfz lame-3.96.1.tar.gz

This will create at least one subdirectory and will unpack all the files into that subdirectory.

A word about the tar command: the command line arguments (xvfz) tell tar what to do. The 'x' means extract, the 'v' means verbose', the 'f' means use an archive file (in this case, lame-3.96.1.tar.gz) and the 'z' means to gunzip the archive before unpacking it. If your program comes in a bzip package (.bz2 extension), then the arguments would be xvfj.

3. Go into the created subdirectory. For our example, the command to do this would be

cd lame-3.96.1

4. Look for instructions on how to compile and install this program. There will be a file, usually with a name in all caps (like README, INSTALL, etc) that contains instruction on how to compile and install the program. You can read these files with the 'less' command:

less INSTALL

Use the regular navigation keys to get around in the file. Type 'q' to leave it.

5. The normal steps for doing the compiling and installing are

./configure
make
su -c "make install"

Note that the last command is done with the root account, This is necessary because the installation may write files to directories for which the normal user account has no write access.

The 'configure' command looks at your system and determines if it contains everything necessary to create the program executable file. The 'make' command actually builds the program executable, and the 'make install' command installs it.

That's all there is to it. Have fun!

Tuesday, 14 February, 2006

Tuesday, 14 February, 2006

Filed under: Uncategorized — nilug @ 12:54 pm

Google and CodeWeavers Inc. are [link=http://www.desktoplinux.com/news/NS9556554213.html]working together to bring Google's popular Windows Picasa photo editing and sharing program to Linux[/link]. The program is now in a limited beta test. If this program is successful, other Google applications will be following it to the Linux desktop, sources say.