Notes on Shell Programming

Notes on Shell Programming

Special Parameters


The number of arguments passed to the program; or the number of parameters set by executing the set statement


Collectively references all the positional parameters as $1, $2, ...


Same as $*, except when double-quoted ("$@") collectively references all the positional parameters as "$1", "$2", ...


The name of the program being executed


The process id number of the program being executed

grep -v "$name" phonebook > /tmp/phonebook$$


The process id number of the last program sent to the background for execution


The exit status of the last command not executed in the background


The current option flags in effect

Other Variables Used by the Shell Variable


The directories to be searched whenever cd is executed without a full path as argument.


The name of a file that the shell executes in the current environment when started interactively.


The editor used by fc. If not set, ed is used.


If set, it specifies a file to be used to store the command history. If not set or if the file isn't writable, $HOME/.sh_history is used.


If set, specifies the number of previously entered commands accessible for editing. T



The Internal Field Separator characters; used by the shell to delimit words when parsing the command line, for the read and set commands, when substituting the output from a back-quoted command, and when performing parameter substitution. Normally, it contains the three characters space, horizontal tab, and newline.



The process id number of the program that invoked this shell (that is, the parent process).

PS1: The primary command prompt, normally "$ ".

PS2: The secondary command prompt, normally "> ".


Parameter Substitution

$parameter or ${parameter}

To access the tenth and greater arguments, you must write ${10}.


whatever was previously stored inside $2 will be assigned to $1, The old value of $1 will be irretrievably lost. When this command is executed, $# (the number of arguments variable) is also automatically decremented by one.

You can shift more than one "place" at once by writing a count immediately after shift, as in

shift 3


Substitute the value of parameter if it's set and non-null; otherwise, substitute value.


Substitute the value of parameter if it's set; otherwise, substitute value.


Substitute the value of parameter if it's set and non-null; otherwise, substitute value and also assign it to parameter.


Substitute the value of parameter if it's set; otherwise, substitute value and also assign it to parameter.


Substitute the value of parameter if it's set and non-null; otherwise, write value to standard error and exit. If value is omitted, write parameter: parameter null or not set instead.


Substitute the value of parameter if it's set; otherwise, write value to standard error and exit. If value is omitted, write parameter: parameter null or not set instead.


Substitute value if parameter is set and non-null; otherwise, substitute null.


Substitute value if parameter is set; otherwise, substitute null.


Substitute the length of parameter. If parameter is * or @, the result is not specified.


Substitute the value of parameter with pattern removed from the left side. The smallest portion of the contents of parameter matching pattern is removed. Shell filename substitution characters (*, ?, [...], !, and @) may be used in pattern.


Same as #pattern except the largest matching pattern is removed.


Same as #pattern except pattern is removed from the right side.


Same as ##pattern except the largest matching pattern is removed from the right side. Quoting

'…' Removes special meaning of all enclosed characters

"…" Removes special meaning of all enclosed characters except $, `, and \


Removes special meaning of character c that follows; inside double quotes removes special meaning of $, `, ", newline, and \that follows, but is otherwise not interpreted; used for line continuation if appears as last character on line (newline is removed)

Using the Backslash for Continuing Lines

The Backslash Inside Double Quotes

The backslash inside these quotes removes the meaning of characters that otherwise would be interpreted inside double quotes (that is, other backslashes, dollar signs, back quotes, newlines, and other double quotes). If the backslash precedes any other character inside double quotes, the backslash is ignored by the shell and passed on to the program:

Command Substitution

The Back Quote `command`

The $(...) Construct $(command)


The expr Command(for older linux)

expr 10 + 20 / 2

Each operator and operand given to expr must be a separate argument,

expr 17 * 6

The shell saw the * and substituted the names of all the files in your directory!

expr 17 \* 6

only use the command substitution mechanism to assign the output from expr back to the variable:

$ i=$(expr $i + 1) Add 1 to i

like the shell's built-in integer arithmetic, expr only evaluates integer arithmetic expressions. You can use awk or bc if you need to do floating point calculations.



if who | grep "^$user " > /dev/null


echo "$user is logged on"


if command






if command



elif command2


elif commandn




The test Command

test String Operators

Operator Returns TRUE (exit status of 0) if

string1 = string2, string1 != string2, string

-n string

string is not null (and string must be seen by test).

-z string

string is null (and string must be seen by test).

An Alternative Format for test

[ expression ]

spaces must appear after the [ and before the ].

[ "$name" = julio ]

Integer Operators

int1 -eq int2

int1 -ge int2

int1 -gt int2

int1 -le int2

int1 -lt int2

int1 -ne int2

File Operators

-d file file is a directory.

-e file file exists.

-f file file is an ordinary file.

-r file file is readable by the process.

-s file file has nonzero length.

-w file file is writable by the process.

-x file file is executable.

-L file file is a symbolic link.

The Logical Negation Operator !

The Logical AND Operator –a

The Logical OR Operator –o

[ -f "$mailfile" -a -r "$mailfile" ]


Use parentheses in a test expression to alter the order of evaluation; and make sure that the parentheses are quoted because they have a special meaning to the shell.

[ \( "$count" -ge 0 \) -a \( "$count" -lt 10 \) ]

The exit Command

The case Command

hour=$(date +%H)

case "$hour"


0? | 1[01] ) echo "Good morning";;

1[2-7] ) echo "Good afternoon";;

* ) echo "Good evening";;


The -x Option for Debugging Programs

You can trace the execution of any program by typing sh -x followed by the name of the program.

The Null Command :

The && and || constructs implement shortcut logic

enable you to execute a command based on whether the preceding command succeeds or fails.

sort bigdata > /tmp/sortout && mv /tmp/sortout bigdata

[ -z "$EDITOR" ] && EDITOR=/bin/ed

grep "$name" phonebook || echo "Couldn't find $name"

The for Command

for i in 1 2 3


echo $i


The $@ Variable

Whereas the shell replaces the value of $* with $1, $2, ..., if you instead use the special shell variable "$@" it will be replaced with "$1", "$2", ... .

The for Without the List

for var




Shell automatically sequences through all the arguments typed on the command line, just as if you had written

for var in "$@"




The while Command

The while loop is often used in conjunction with the shift command to process a variable number of arguments typed on the command line.

while [ "$#" -ne 0 ]


echo "$1"



The until Command

until who | grep "^$user " > /dev/null


sleep 60



When the break is executed, control is sent immediately out of the loop, where execution then continues as normal with the command that follows the done.

break n the n innermost loops are immediately exited.

continue n causes the commands in the innermost n loops to be skipped; but execution of the loops then continues as normal.

Executing a Loop in the Background

An entire loop can be sent to the background for execution simply by placing an ampersand after the done.

for file in memo[1-4]


run $file

done &

I/O Redirection on a Loop

Input/Output redirected into the loop applies to all commands in the loop that read their data from standard input or write to standard can also redirect the standard error output from a loop, simply by tacking on a 2> file after the done.

You can override redirection of the entire loop's input or output by explicitly redirecting the input and/or output of commands inside the loop. To force input or output of a command to come from or go to the terminal, use the fact that /dev/tty always refers to your terminal.

for file


echo "Processing file $file" > /dev/tty

done > output

Piping Data Into and Out of a Loop

A command's output can be piped into a loop, and the entire output from a loop can be piped into another command in the expected manner.

for i in 1 2 3 4


echo $i

done | wc -l

Typing a Loop on One Line

for i in 1 2 3 4; do echo $i; done

if commands can also be typed on the same line using a similar format:

if [ 1 = 1 ]; then echo yes; fi

The getopts Command

getopts options variable

The getopts command is designed to be executed inside a loop. Each time through the loop, getopts examines the next command line argument and determines whether it is a valid option. This determination is made by checking to see whether the argument begins with a minus sign and is followed by any single letter contained inside options. If it does, getopts stores the matching option letter inside the specified variable and returns a zero exit status.

If the letter that follows the minus sign is not listed in options, getopts stores a question mark inside variable before returning with a zero exit status. It also writes an error message to standard error.

If no more arguments are left on the command line or if the next argument doesn't begin with a minus sign, getopts returns a nonzero exit status.

To indicate to getopts that an option takes a following argument, you write a colon character after the option letter on the getopts command line.

getopts mt: option

If getopts doesn't find an argument after an option that requires one, it stores a question mark inside the specified variable and writes an error message to standard error. Otherwise, it stores the actual argument inside a special variable called OPTARG.

Another special variable called OPTIND is initially set to one and is updated each time getopts returns to reflect the number of the next command-line argument to be processed.

while getopts mt: option


case "$option"


m) mailopt=TRUE;;

t) interval=$OPTARG;;

\?) echo "Usage: mon [-m] [-t n] user"

exit 1;;



shiftcount=$((OPTIND – 1))

shift $shiftcount


Reading and Printing Data

The read Command read variables

You can use the –r option to read to prevent shell interpreting the backslash character.

while read –r line

Special echo Escape Characters \c

\c tells echo to leave the cursor right where it is after displaying the last argument and not to go to the next line.

The printf Command

printf "format" arg1 arg2 ...

printf Conversion Specification Modifiers

- Left justify value.

+ Precede integer with + or -.

(space) Precede positive integer with space character.

# Precede octal integer with 0, hexadecimal integer with 0x or 0X.

Width Minimum width of field; * means use next argument as width.


Minimum number of digits to display for integers; maximum number of characters to display for strings; * means use next argument as precision.

More on Subshells

A subshell can't change the value of a variable in a parent shell, nor can it change its current directory.

The . Command

Its purpose is to execute the contents of file in the current shell, A subshell is not spawned to execute the program.

The (...) and { ...; } Constructs

They are used to group a set of commands together.

The first form causes the commands to be executed by a subshell, the latter form by the current shell.

For {}., if the commands enclosed in the braces are all to be typed on the same line, a space must follow the left brace, and a semicolon must appear after the last command.

.profile File

/etc/profile and $HOME/.profile

I/O Redirection

< file, > file

>| file

Redirect standard output to file; file is created if it doesn't exist and zeroed if it does; the noclobber (-C) option to set is ignored.

>> file

Like >, only output is appended to file if it already exists.

Redirect the standard output for a command to standard error by writing

command >& 2

Collect the standard output and the standard error output from a program into the same file.

command >foo 2>>foo or command >foo 2>&1

Because the shell evaluates redirection from left to right on the command line, the last example cannot be written: command 2>&1 > foo

Inline Input Redirection

command <<word


the shell uses the lines that follow as the standard input for command, until a line that contains just word is found.

The shell performs parameter substitution for the redirected input data, executes back-quoted commands, and recognizes the backslash character. However, any other special characters, such as *, |, and ", are ignored. If you have dollar signs, back quotes, or backslashes in these lines that you don't want interpreted by the shell, you can precede them with a backslash character. Alternatively, if you want the shell to leave the input lines completely untouched, you can precede the word that follows the << with a backslash.

If the first character that follows the << is a dash (-), leading tab characters in the input will be removed by the shell.

<& digit Standard input is redirected from the file associated with file descriptor digit.

>& digit Standard output is redirected to the file associated with file descriptor digit.

<&- Standard input is closed.

>&- Standard output is closed.

<> file Open file for both reading and writing.

Shell Archives

One or more related shell programs can be put into a single file and then shipped to someone.

cat > program_name <<\THE-END-OF-DATA


The exec Command

Because the exec'ed program replaces the current one, there's one less process hanging around; also, startup time of an exec'ed program is quicker, due to the way the Unix system executes processes.

exec can be used to close standard input and reopen it with any file that you want to read. To change standard input to file:

exec < file

Redirection of standard output is done similarly: exec > report

If you use exec to reassign standard input and later want to reassign it someplace else, you can simply execute another exec. To reassign standard input back to the terminal, you would write

exec < /dev/tty

The set Command

General Format: set options args

This command is used to turn on or off options as specified by options. It is also used to set positional parameters, as specified by args.

Each single letter option in options is enabled if the option is preceded by a minus sign (-), or disabled if preceded by a plus sign (+).

set Options


-- option tells set not to interpret any subsequent arguments on the command line as options. It also prevents set from displaying all your variables if no other arguments follow.


Automatically export all variables that are subsequently defined or modified.


Print each shell command line as it is read.


Print each command and its arguments as it is executed,

set with No Arguments

Using set to Reassign Positional Parameters

There is no way to directly assign a value to a positional parameter;

These parameters are initially set on execution of the shell program. The only way they may be changed is with the shift or the set commands. If words are given as arguments to set on the command line, those words will be assigned to the positional parameters $1, $2, and so forth. The previous values stored in the positional parameters will be lost forever. So

set a b c

assigns a to $1, b to $2, and c to $3. $# also gets set to 3.

The IFS Variable stands for Internal Field Separator.

echo "$IFS" | od -b

The readonly Command

readonly –p gets a list of your read-only variables

The unset Command

unset x Remove x from the environment

This causes the shell to erase definitions of the variables or functions listed in names. Read-only variables cannot be unset. The –v option to unset specifies that a variable name follows, whereas the –f option specifies a function name. If neither option is used, it is assumed that variable name(s) follow.

The eval Command

eval command-line

the net effect is that the shell scans the command line twice before executing it.


ls $pipe wc -l

The shell takes care of pipes and I/O redirection before variable substitution, so it never recognizes the pipe symbol inside pipe.

eval ls $pipe wc –l

The first time the shell scans the command line, it substitutes | as the value of pipe. Then eval causes it to rescan the line, at which point the | is recognized by the shell as the pipe symbol.

Get the last parameter: eval echo \$$#

The wait Command

wait process-id

where process-id is the process id number of the process you want to wait for. If omitted, the shell waits for all child processes to complete execution.

The trap Command

trap commands signals

Commonly Used Signal Numbers

0 Exit from the shell

1 Hangup

2 Interrupt (for example, Delete, Ctrl+c key)

15 Software termination signal (sent by kill by default)

trap "rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit" 1 2

The value of WORKDIR and $$ will be substituted at the time that the trap command is executed. If you wanted this substitution to occur at the time that either signal 1 or 2 was received (for example, WORKDIR may not have been defined yet), you can put the commands inside single quotes:

trap 'echo logged off at $(date) >>$HOME/logoffs' 0

trap 'rm $WORKDIR/work1$$ $WORKDIR/dataout$$; exit' 1 2

trap with No Arguments

Executing trap with no arguments results in the display of any traps that you have changed.

Ignoring Signals

If the command listed for trap is null, the specified signal will be ignored when received.

trap "" 2

If you ignore a signal, all subshells also ignore that signal. However, if you specify an action to be taken on receipt of a signal, all subshells will still take the default action on receipt of that signal.

If you execute trap : 2

and then execute your subshells, then on receiving the interrupt signal the current shell will do nothing (it will execute the null command), but all active subshells will be terminated (they will take the default action—termination).

Resetting Traps

After you've changed the default action to be taken on receipt of a signal, you can change it back again with trap if you simply omit the first argument;

trap 1 2


name () { command; ... command; }

Removing a Function Definition

To remove the definition of a function from the shell, you use the unset command with the –f option.

unset –f nu


Unix Shell Programming, Third Edition

Post a Comment


Java (159) Lucene-Solr (110) All (60) Interview (59) J2SE (53) Algorithm (37) Eclipse (35) Soft Skills (35) Code Example (31) Linux (26) JavaScript (23) Spring (22) Windows (22) Web Development (20) Tools (19) Nutch2 (18) Bugs (17) Debug (15) Defects (14) Text Mining (14) J2EE (13) Network (13) PowerShell (11) Chrome (9) Continuous Integration (9) How to (9) Learning code (9) Performance (9) UIMA (9) html (9) Design (8) Dynamic Languages (8) Http Client (8) Maven (8) Security (8) Trouble Shooting (8) bat (8) blogger (8) Big Data (7) Google (7) Guava (7) JSON (7) Problem Solving (7) ANT (6) Coding Skills (6) Database (6) Scala (6) Shell (6) css (6) Algorithm Series (5) Cache (5) IDE (5) Lesson Learned (5) Miscs (5) Programmer Skills (5) System Design (5) Tips (5) adsense (5) xml (5) AIX (4) Code Quality (4) GAE (4) Git (4) Good Programming Practices (4) Jackson (4) Memory Usage (4) OpenNLP (4) Project Managment (4) Python (4) Spark (4) Testing (4) ads (4) regular-expression (4) Android (3) Apache Spark (3) Become a Better You (3) Concurrency (3) Eclipse RCP (3) English (3) Firefox (3) Happy Hacking (3) IBM (3) J2SE Knowledge Series (3) JAX-RS (3) Jetty (3) Restful Web Service (3) Script (3) regex (3) seo (3) .Net (2) Android Studio (2) Apache (2) Apache Procrun (2) Architecture (2) Batch (2) Build (2) Building Scalable Web Sites (2) C# (2) C/C++ (2) CSV (2) Career (2) Cassandra (2) Distributed (2) Fiddler (2) Google Drive (2) Gson (2) Html Parser (2) Http (2) Image Tools (2) JQuery (2) Jersey (2) LDAP (2) Life (2) Logging (2) Software Issues (2) Storage (2) Text Search (2) xml parser (2) AOP (1) Application Design (1) AspectJ (1) Bit Operation (1) Chrome DevTools (1) Cloud (1) Codility (1) Data Mining (1) Data Structure (1) ExceptionUtils (1) Exif (1) Feature Request (1) FindBugs (1) Greasemonkey (1) HTML5 (1) Httpd (1) I18N (1) IBM Java Thread Dump Analyzer (1) JDK Source Code (1) JDK8 (1) JMX (1) Lazy Developer (1) Mac (1) Machine Learning (1) Mobile (1) My Plan for 2010 (1) Netbeans (1) Notes (1) Operating System (1) Perl (1) Problems (1) Product Architecture (1) Programming Life (1) Quality (1) Redhat (1) Redis (1) Review (1) RxJava (1) Solutions logs (1) Team Management (1) Thread Dump Analyzer (1) Troubleshooting (1) Visualization (1) boilerpipe (1) htm (1) ongoing (1) procrun (1) rss (1)

Popular Posts