A UNIX shell is essentially the API between the user, the kernel, and the system hardware. The shell is very important on any UNIX or Linux system and is one of the most vital aspects to learn proper systems administration and security. Typically driven by a CLI, the shell can literally make or break your system. The open source bash shell that this article examines is one of the most powerful, practical, and extensible shells available. In this article, you will learn the basic techniques of bash scripting, its everyday uses, and methods for employing it to create near-bulletproof shell scripts.
The Bourne Again Shell (bash) got its start in 1987, when it was written as a GNU project that many Linux distributions quickly adopted. Currently, many different versions of bash are freely available.
One of the more positive aspects of bash is its built-in security features. Bash keeps a record of what the user has typed exactly and writes it to a hidden file called .bash_history within the user’s home directory. So, if you implement bash, you can easily track your systems users much more closely. In fact, for many Linux systems, bash is commonly preinstalled as the default shell environment.
Bash command syntax and keywords have taken and improved upon the architecture
and technical details of the Korn shell (ksh) and the C
shell (csh). In addition, bash's syntax has many extensions that other shells lack.
Integer calculations are more efficiently completed in bash than in other shells,
and bash can redirect standard output (stdout) and standard error (stderr) more
easily than older shells.
Bash is also ideal for secure environments, having a restricted start mode that can confine a user's ability within the shell to a brief, determinable list of commands. Open to modification, you can edit your own set of bash shell login control files—namely hidden files, such as .bashrc, .bash_profile, .bash_logout, and .profile—to customize your login shell.
Uses and functions of the bash shell
To write effective bash shell scripts, you must master the basic bash command set for navigation and daily routine tasks performed within the shell.
Upon login, users typically have a global profile as well as two personal files that are executed (.bash_profile and .bashrc). Figure 1 shows the usual process flow.
Figure 1. The bash shell login process
Now, take a look at a typical Linux user’s .bash_profile (Listing 1) and .bashrc (Listing 2) scripts. These scripts are loaded from the user's home directory.
Listing 1. A typical .bash_profile file
[fred.smythe@server01 ~]$ cat .bash_profile
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
export JAVA_HOME=/usr/java/default
export PATH=$JAVA_HOME/bin:$PATH
PATH=$PATH:$HOME/bin
export PATH
|
In the .bashrc file in Listing 2, some user aliases are configured, and the global bashrc file is loaded if it exists.
Listing 2. A typical .bashrc file
[fred.smythe@server01 ~]$ cat .bashrc
# .bashrc
# User specific aliases and functions
alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias tc6='cd /opt/tomcat/6.0.13'
alias conf6='cd /opt/tomcat/6.0.13/conf'
alias bin6='cd /opt/tomcat/6.0.13/bin'
alias scr='cd /opt/tomcat/scripts'
alias reports='cd /opt/tomcat/reports'
alias temp6='cd /opt/tomcat/6.0.13/template'
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
|
The system level process init spawns the getty or agetty process. This process in turn calls the /bin/login program, which presents the familiar UNIX or Linux login prompt. The user proceeds to login to access the system, at which point the login program spawns a new bash shell. When a bash shell user logs in, the following events occur in this order: the global profile is read; the user's individual bash profile is read; and then the user's personal '.bashrc' is read, which will typically set aliases, define additional functions, and define the user's individual environmental variables. Lastly, the bash user is presented with a bash shell prompt, and the motd file is read and displayed. Figure 2 below is an illustrated example.
Figure 2. Bash shell login process details
The user then has a standard command set of programs available to him or her from within your bash shell environment $PATH variable. If a command isn't in the user's $PATH, but he or she has permissions to execute the command, you must use the full path, as shown in Listing 3.
Listing 3. Example of $PATH issues within the bash shell
[fred.smythe@server01 ~]$ ifconfig -a -bash: ifconfig: command not found [fred.smythe@server01 ~]$ which ifconfig /usr/bin/which: no ifconfig in (/usr/local/bin:/bin:/usr/bin:/home/fred.smythe/bin) |
This issue comes up when the binary program ifconfig
is not within the user’s defined PATH variable. However, if you know the full
path of the command, you can run it as shown in Listing 4.
Listing 4. Using the full path of a command to overcome a $PATH issue in the bash shell
[fred.smythe@server01 ~]$ /sbin/ifconfig -a
eth0 Link encap:Ethernet HWaddr 00:50:56:96:2E:B3
inet addr:10.14.33.60 Bcast:10.14.33.255 Mask:255.255.255.0
|
Listing 5 shows a method using an alias to overcome the $PATH issue. Within your bash scripts, you may want to run commands with the full path, depending on who will run the intended script.
Listing 5. Setting an alias to overcome a $PATH issue in the bash shell
[fred.smythe@server01 ~]$ alias ifconfig='/sbin/ifconfig'
[fred.smythe@server01 ~]$ ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:56:96:2E:B3
inet addr:10.14.33.60 Bcast:10.14.33.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
|
When a command or the bash shell itself initiates (or spawns) a new shell
sub-process to perform a task, it is known as forking. When
this new process—the child process—is executing, the
parent process will still be running. If a parent process should die before
the child process, the child process can become a defunct process—also
known as a zombie process which usually results in a hung process
or hung application. Thus, this hung process must be killed or terminated
abnormally. Although a parent process can access the process ID of its child
process and can thus pass arguments to it, the reverse is false. When a shell
script process exits or returns to the parent process, the exit code should be
0. If it is anything else, there was likely an error
or problem with the process.
The exit code of the last command executed—echo
$?—is shown in Listing 6.
Listing 6. Exit code examples
# ls -ld /tmp drwxrwxrwt 5 root root 4096 Aug 19 19:45 /tmp [root@server01 ~]# echo $? 0 // Good command return of 0. [root@server01 ~]# ls -l /junk ls: /junk: No such file or directory [root@server01 ~]# echo $? 2 // Something went wrong, there was an error, so return 2. |
Listing 7 illustrates a parent and child process shown within a bash environment.
Listing 7. Example of a parent and child process in a bash environment
[root@server02 htdocs]# ps -ef | grep httpd UID PID PPID C STIME TTY TIME CMD root 8495 1 0 Jul26 ? 00:00:03 /usr/sbin/httpd -k start apache 9254 8495 0 Aug15 ? 00:00:00 /usr/sbin/httpd -k start |
If you type the command env, you see what your
current bash shell default environmental variables are set to, including your
user name and tty (terminal) information, your $PATH values, and your present
working directory ($PWD). Take a look at Listing 8.
Listing 8. Example of a bash environment
[fred.smythe@server01 ~]$ env HOSTNAME=server01 TERM=screen SHELL=/bin/bash HISTSIZE=1000 SSH_CLIENT=10.12.132.3 56513 22 SSH_TTY=/dev/pts/0 USER=fred.smythe LS_COLORS=no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:bd=40;33;01:cd=40;33;01:or=01;05 ;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32 :*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip= 01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.rpm=01;31:*.cpio= 01;31:*.jpg=01;35:*.gif=01;35:*.bmp=01;35:*.xbm=01;35:*.xpm=01;35:*.png=01;35:*.tif=01;35: MAIL=/var/spool/mail/fred.smythe PATH=/usr/local/bin:/bin:/usr/bin:/home/fred.smythe/bin INPUTRC=/etc/inputrc PWD=/home/fred.smythe LANG=en_US.UTF-8 SHLVL=1 HOME=/home/fred.smythe LOGNAME=fred.smythe SSH_CONNECTION=10.14.43.183 56513 10.14.43.43 22 LESSOPEN=|/usr/bin/lesspipe.sh %s G_BROKEN_FILENAMES=1 _=/bin/env |
You can navigate your Linux file systems using the bash commands shown in Listing 9.
Listing 9: Navigating in a bash environment
[fred.smythe@server01 ~]$ ls -l
total 0
[fred.smythe@server01 ~]$ cd /tmp
[fred.smythe@server01 tmp]$ df -ha .
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_root-lv_tmp
2.0G 68M 1.8G 4% /tmp
|
In the listing, commands were issued one at a time. But, you could have run them
together using the semi-colon (;) separator, as
shown in Listing 10.
Listing 10: Sequential command execution in bash
[fred.smythe@server01 tmp]$ ls -l ;cd /tmp;df -ha .
total 40
-rw-r----- 1 root root 1748 May 22 2009 index.html
-rw-r----- 1 root root 786 Aug 17 04:59 index.jsp
drwx------ 2 root root 16384 Jul 15 2009 lost+found
drwx------ 2 root root 4096 Aug 9 21:04 vmware-root
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_root-lv_tmp
2.0G 68M 1.8G 4% /tmp
[fred.smythe@server01 tmp]$
|
On the bash command-line, command completion shortens the typing needed for everyday tasks. Simply type the beginning of a command, then press the Tab key. Note that if you cannot access the command or file because of permissions restrictions, command completion won't function for you.
Bash provides several forms of help:
man(shown below in Listing 11):
Listing 11. Example of man pages in bash[fred.smythe@server01 tmp]$ man perl PERL(1) Perl Programmers Reference Guide PERL(1) NAME perl - Practical Extraction and Report Language SYNOPSIS perl [ -sTtuUWX ] [ -hv ] [ -V[:configvar] ] -cw ] [ -d[t][:debugger] ] [ -D [num- ber/list] ] [ -pna ] [ -Fpattern ] [ -l[octal] ] [ -0[octal/hexadecimal] ] [ -Idir ] [ -m[-]module ] [ -M[-] module... ] [ -f ] [ -C [number/list] ] [ -P ] [ -S ] [ -x[dir] ] [ -i[extension] ] [ -e command ] [ -- ] [ program- file ] [ argument ]...
whatis(shown below in Listing 12):
Listing 12. Example of the whatis command in bash[fred.smythe@server01 tmp]$ whatis perl perl (1) - Practical Extraction and Report Language perl (rpm) - The Perl programming language
apropos(shown below in Listing 13):
Listing 13. Apropos example in bash[root@server01 ~]# apropos perl | more B (3pm) - The Perl Compiler B::Asmdata (3pm) - Autogenerated data about Perl ops, used to generate bytecode B::Assembler (3pm) - Assemble Perl bytecode
which(shown below in Listing 14):
Listing 14. The which command in bash[root@server01 ~]# which perl /usr/bin/perl
The bash shell contains two types of commands: builtins, which are internal,
and external programs (or external filters and commands), which are
typically self-contained binary program files. Listing 15 shows
how to find the built-in commands in bash using the alias
command.
Listing 15. Finding the built-in commands within bash
[root@server01 ~]# man -k builtins| more . [builtins] (1) - bash built-in commands, see bash(1) : [builtins] (1) - bash built-in commands, see bash(1) [ [builtins] (1) - bash built-in commands, see bash(1) alias [builtins] (1) - bash built-in commands, see bash(1) bash [builtins] (1) - bash built-in commands, see bash(1) bg [builtins] (1) - bash built-in commands, see bash(1) bind [builtins] (1) - bash built-in commands, see bash(1) break [builtins] (1) - bash built-in commands, see bash(1) builtin [builtins] (1) - bash built-in commands, see bash(1) |
To identify a specific command in bash, use the type
command, as shown in Listing 16.
Listing 16. Finding the built-ins commands using the type command
[root@apache-02 htdocs]# type lsof lsof is /usr/sbin/lsof [root@apache-02 htdocs]# type alias alias is a shell builtin |
Listing 17 provides an example of lsof, an external command. This command is actually a binary file residing
in the Linux file system; it's installed via a package of the same name.
Listing 17. Finding the external command details within bash
[root@server01 ~]# which lsof /usr/sbin/lsof [root@server01 ~]# rpm -qa lsof-4.78-3.i386 [root@server01 ~]# rpm -qa lsof lsof-4.78-3.i386 |
One of the bash shell's most powerful features is its ability to allow command-line scripting on the fly. Consider the example in Listing 18, which sets a shell variable, tests for the value of the variable, and then programmatically executes another command if the value is greater than zero.
Listing 18. Scripting on the fly with bash
[fred.smythe@server01 ~]$ DEBUG=1 [fred.smythe@server01 ~]$ test $DEBUG -gt 0 && echo "Debug turned on" Debug turned on |
Here's an example of a for loop written on the fly
(shown in Listing 19). Note that here, you're typing interactively
at the shell prompt; at each >, you type
the next line of your interactive shell script.
Listing 19. A for loop written on the fly within bash
$ for SVR in 1 2 3 > do > echo server0$SVR.example.com > done server01.example.com server02.example.com server03.example.com |
Note that alternatively, you could have run this code as sequential commands separated by semi-colons.
The command for is not a program but a kind of
special built-in known as a keyword. The list of keywords in the
average distribution of bash on Linux are shown in Listing 20.
Listing 20. Keywords within bash
true, false, test, case, esac, break, continue, eval, exec, exit, export, readonly, return, set, shift, source, time, trap, unset, time, date, do, done, if, fi, else, elif, function, for, in, then, until, while, select |
You should avoid these keywords—or what are known as bash shell reserved words—when choosing names for shell variables.
The bash shell lets you redirect standard input, standard output, and standard error on a Linux or UNIX system. Consider the examples in Listing 21.
Listing 21. Piping commands together inside bash
$ USER="fred.smythe"
$ echo -n "User $USER home is: " && cat /etc/passwd | grep $USER | awk -F: '{print $6}'
User fred.smythe home is: /home/fred.smythe
$
# Re-direction of standard output (>) of the date command to a file :
[root@server01 ~]# date > /tmp/today.txt
[root@server01 ~]# cat /tmp/today.txt
Thu Aug 19 19:38:33 UTC 2010
# Re-direction of standard input (<) to standard output (>) …
[root@server01 ~]# cat < /tmp/today.txt > /tmp/today.txt.backup
[root@server01 ~]# cat /tmp/today.txt.backup
Thu Aug 19 19:38:33 UTC 2010
|
Compound command lines can use and combine multiple instances of standard input, standard output, and standard error redirection and/or pipes to perform exacting operations with high degrees of precision and accuracy. Listing 22 provides an example.
Listing 22. Example of re-direction inside bash
# command1 < input_file1.txt > output_file1.txt # command1 | command2 | command3 > output_file.log |
You can use complex combined command lines, for example, to find Apache permission-denied errors by searching within all found compressed error logs and counting the number of errors.
$ find ./ -name 'error_log.*.gz' | xargs zcat | grep 'Permission denied'| wc -l 3 |
To achieve production-quality or enterprise-level scripting, here are a few key points to keep in mind:
- Always comment your scripts with a brief heading.
- Comment your code heavily so that at a later date, you can easily remember
the reason your source code was written as it is. Remember that the
first line of your script needs to be the
#!/bin/bashline. - Write your script actions to a log file, with a date and timestamp for later
examination. Be verbose with your output, log success messages, and
clearly state error messages or conditions. It's also probably wise
to log the start and stop time of your script. Using the
teecommand, you can append to a log and standard output at the same time:DATEFMT=`date "+%m/%d/%Y %H:%M:%S"` echo "$DATEFMT: My message" | tee -a /tmp/myscript.log
- If your scripts write to a log file, always create a new log file and include
the date, hour, minute, and even the seconds in the new log's file name.
Then, with a simple
findcommand, you can easily rotate and compress your script's own logs each time you run it:DATELOG=`date "+%m%d%y"` LOGFILE="/data/maillog/mail_stats.log.$DATELOG" # gzip the old mail_stats logs, older than 7 days find /logs -type f -name "mail_stats.log.????????????" -mtime +7 | xargs gzip -9 # remove the old gzipped mail_stats logs after 30 days find /logs -type f -name "mail_stats.log.*.gz" -mtime +30 -exec rm {} \; # mail_log utility log resets echo "" > /var/log/mail_stats.log.$DATELOG
- Build error-checking logic into your scripts and never assume anything. Doing so will save a tremendous amount of pain and grief later.
- Incorporate the use of functions and shell script libraries (by sourcing in another script) where possible within your script. Doing so reuses tested and proven code and will save you from repeating script code and making potential errors.
- Filter input parameters from users:
NUMPARAMETERS="$#" if [ $NUMPARAMETERS != 3 ];then echo "Insufficient number of parameter passed!” echo “Please run script in format ./myscript.sh $1 $2 $3” exit 2 fi
- Consider adding a debug mode or function within your script—say,
with the
set –xcommand. - Add functions to alert or send a trap for particular events within your script.
You can do this via SNMP commands or an audible bell
(
echo x), and then send an email message with themailcommand. - If you're writing a script that will be used like an interactive menu, consider the user's environmental shell and the commands they have access to. If in doubt, use full paths for all commands within your scripts.
- Add individual and unique return codes to your bash shell script. When you
write a large script, you'll be able to easily identify exactly where an
error or problem is occurring by pin-pointing the return code:
if [ “$ERRCHECK” != “” ];then echo “Error Detected : $ERRCHECK ! Cannot continue, exit $EXITVAL value” exit $EXITVAL fi
- Test your scripts thoroughly in a lab environment for all possible conditions. Have other users perform testing on the scripts, as well, and intentionally try to "break" them.
- If your script is operating on input data from users or a data input file, always thoroughly filter, check, and validate the input data. Scripts that work from a data list can be run on multiple, different sets of data lists, as desired.
- For scripts that will run for a long time, consider placing a timeout function
within the script to terminate or stop after n number of minutes:
stty –icannon min 0 time 1800
- Properly indent your code to make it more readable.
For scripts you write for a specific purpose, you may want to add an interactive warning prompt message to give the user information about the script's purpose. For example, the script in Listing 23 retrieves remote logs and creates a report email.
Listing 23. Simple bash script to retrieve and report on logs
#!/bin/bash
cd /data01/maillog
MAILSVRS=$(/bin/cat /data01/maillog/mail_servers)
DATELOG=`date "+%m%d%y"`
ALLMAILLOGS="/data01/maillog/all_svr_maillogs.$DATELOG"
MAILREPORT="/data01/maillog/all_svr_maillogs.report.$DATELOG"
MAILADDRESSES=$(/bin/cat /data01/maillog/addresses)
MAILADMINS="admin1@example.com, admin2@example.com"
MAILSTATSLOGALL="/data01/maillog/mailstats.log.all.$DATELOG"
DELDAYSLOGS=10
echo “Mail Report to $ MAILADMINS”
# 1 - Get some logs …
for svr in $MAILSVRS
do
if [ -e "/data01/maillog/$svr.maillog.$DATELOG.gz" ]; then
/bin/rm -f /data01/maillog/$svr.maillog.$DATELOG.gz
fi
done
# 2 - Combine all maillogs from all servers to onefile ($ALLMAILLOGS) ...
/bin/zcat server16.maillog.$DATELOG.gz server17.maillog.$DATELOG.gz
server18.maillog.$DATELOG.gz server19.maillog.$DATELOG.gz >>
$ALLMAILLOGS
# 3 - Run another script
/bin/cat $ALLMAILLOGS | /data01/maillog/mymailstats.pl | tee -a $MAILREPORT
# 4 - Get all of the mailstats logs to one log file to send by Email
/bin/cat /data01/maillog/mailstats.log.server*.$DATELOG > $MAILSTATSLOGALL
# Send the $MAILADMINS the mail reports
/bin/cat $MAILSTATSLOGALL | mail -s "ACME Servers Outbound Mail Servers
mailstats:$DATELOG" $MAILADMINS
|
For an improved version of the same script with more robust features, download the source code for this article.
Variables, syntax format, and structure inside bash scripting
Within bash, several methods are valid for defining and setting variables. The script in Listing 24 provides an example of these shell variable declaration methods.
Listing 24. Defining bash variables
$ cat a.sh
#!/bin/bash
A="String Value 1"
B='String Value 2'
C=9675
D=96.75
export E="String Value 3"
# if the variable $F is not ALREADY set to a value, assign "String Value 4" ...
F=${F:="String Value 4"}
echo "A=$A"
echo "B=$B"
echo "C=$C"
echo "D=$D"
echo "E=$E"
echo "F=$F"
exit 0
$ ./a.sh
A=String Value 1
B=String Value 2
C=9675
D=96.75
E=String Value 3
F=String Value 4
|
To gather user input, you use the read statement
and assign a variable to the user input, as shown in Listing 25.
Listing 25. Obtaining user input from a bash script
$ cat prompt.sh #!/bin/bash echo "Please enter your first and last name:" read ans echo "Hellow $ans , welcome to bash scripting ...!" exit 0 $ ./prompt.sh Please enter your first and last name: Joe Jackson Hello Joe Jackson , welcome to bash scripting ...! |
To use a function within your bash shell script, you use the methods shown in Listing 26.
Listing 26. Implementing functions within bash
$ cat function.sh
#!/bin/bash
funcOne() {
echo "Running function 1, with parameter $1"
date
echo "Current listing /tmp directory, last 3 lines"
ls -lrt /tmp | tail -3
}
echo "Hello World"
funcOne "Server01"
exit 0
$ ./function.sh
Hello World
Running function 1, with parameter Server01
Sun Aug 22 22:43:04 UTC 2010
Current listing /tmp directory, last 3 lines
-rw-r- 1 dsmith progdevel 12749743 Aug 16 20:32 files.tar.gz
drwxr-xr-x 2 jjones progdevel 4096 Aug 16 20:42 ff_hosting_files
-rw-r- 1 rhill heng 1440 Aug 22 19:07 myscript.log
|
Or, you can write the function shown in Listing 27.
Listing 27. Alternate function definition within bash
#!/bin/bash
function funcTwo () {
echo "Running function 2, with parameter $1"
date
echo "Current listing /var directory, last 3 lines"
ls -lrt /var | tail -3
}
funcTwo "Server02"
exit 0
$ ./function.sh
Running function 2, with parameter Server02
Sun Aug 22 22:53:16 UTC 2010
Current listing /var directory, last 3 lines
drwxrwxrwt 3 root root 4096 Aug 6 18:22 tmp
drwxr-xr-x 6 root root 4096 Aug 22 04:02 log
drwxrwxr-x 4 root lock 4096 Aug 22 04:22 lock
|
The function keyword is optional. The only rule is
that you need to declare the function before you can use it later in the
program. You invoke the function simply by calling its name and passing on to
it any further required or optional input parameters.
Let's say you need to do some repetitive work on several servers. You can easily use
a for loop within bash to do the job quickly.
Listing 28 shows the code.
Listing 28. Bash scripting example of a simple for loop
$SERVERS=”server01 server02 server03 server04 server05” for i in $SERVERS do echo "Removing file from server: $i" ssh $i rm -f /tmp/junk1.txt done |
A while loop within bash allows you to execute
a statement a given number of times, or until a certain condition is met.
Listing 29 provides an example.
Listing 29. A simple while loop
LOOPCTR=1 while [ $LOOPCTR -lt 6 ] do echo “Running patch script for server0$LOOPCTR” /data/patch.sh server0$LOOPCTR LOOPCTR=`expr $LOOPCTR + 1` done |
A case statement within bash lets you test
for more than one condition or value and act accordingly. Using such a
statement can sometimes be a better route than nested
for loops or if
statements to cut down on repetitive code or just for better structure.
Listing 30 shows a brief case
statement that make calls to functions, depending on the condition of the
variable $key.
Listing 30. Example of a case statement in bash
case $key in
q) logit "Quit";
exit;;
1) echo “\tChecking Mail Servers”;
check_mail_servers;;
2) echo "\tChecking Web Servers";
check_web_servers;;
3) echo “\tChecking App Servers;
check_app_servers;;
4) echo “\tChecking Database Servers”;
check_database_servers;;
b) echo "Go Back to Main menu";
MENUFLAG="main";
main_menu;;
*) echo "$key invalid choice";
invalid;;
esac
|
Pros and cons of bash scripting
Need something done quickly? If you've got bash, you can cut down the time needed to write the newest corporate gizmo web widget like a chainsaw going through warm butter. Bash scripting is not a programming language or an application. No compiler is required, and you don't need special libraries or a software development environment to work from. But bash shell scripts can act like applications and even perform some of the tasks and jobs that applications can do.
On the pro side, bash offers:
- Fast development time and code that is easily modifiable. The basics of bash scripting change little over time.
- Fairly straightforward syntax in comparison with some programming languages, where depending on the programming language, coding or syntactical changes may be frequent.
- Advanced bash features (for example, epoch, functions, signal control, multiple extensions, command history, the means of using one-dimensional arrays) that give users much more power than before.
- Nothing much beyond a *nix bash shell required to perform bash shell scripting.
On the con side, bash code:
- Is executed by the shell, then passed to the kernel, which is typically slower than a compiled binary program that is pure machine code. As a result, bash shell scripting may be undesirable for some application designs or functions.
- Is clear text or easily viewable by anyone with Read permissions, whereas compiled binaries are not readable. This poses a huge security risk when trying to encode sensitive data.
- Has no particular set of standard functions, whereas many modern programming languages have intrinsic or built-in functions for various programmatic needs.
Now that you have the basics of bash shell scripting well in hand, you must promise to only use your powers for the greater good. So, go out and save the *nix world with your newly found crontabs, one-line wonders, and interactive menus. Don't be afraid to be a "bash" administrator!
| Description | Name | Size | Download method |
|---|---|---|---|
| Sample bash shell scripts | Bash_Source.zip | 8KB | HTTP |
Information about download methods
Learn
-
Check out the GNU bash reference
manual—a user guide to bash syntax.
-
Wikipedia provides a good definition
of the bash shell.
-
Examine a comparison
of shells to see how bash stacks up against the others.
-
Check out bash basics for
beginners.
-
AIX and UNIX developerWorks
zone: The AIX and UNIX zone provides a wealth of information relating to
all aspects of AIX systems administration and expanding your UNIX skills.
-
New to AIX and UNIX?
Visit the New to AIX and UNIX page to learn more.
-
Technology
bookstore: Browse the technology bookstore for books on this and other
technical topics.
Get products and technologies
-
Download bash and get
the resources you need to start working with the bash shell now.
-
Peruse the list of shells
available for UNIX and Linux.
Discuss
-
developerWorks blogs: Check out
our blogs and get involved in the developerWorks
community.
- Follow developerWorks on Twitter.
-
Participate in the AIX and UNIX® forums:
- AIX Forum
- AIX Forum for developers
- Cluster Systems Management
- Performance Tools Forum
- Virtualization Forum
- More AIX and UNIX Forums
Roger Hill has worked as a UNIX®/Linux® systems engineer and programmer/developer in large, complex hybrid environments for the past 23 years. His specialization for the past seven years has been on intercommunications between various UNIX, Linux, and Windows® platforms and creating seamless and secure automation for such systems. Roger holds an Associate's Degree in Computer Information Systems, a Bachelor's Degree in Computer Science, and a Chancellor's Certificate in Linux Administration and maintains nine professional technical certifications.



