Bash is a huge subject! The purpose of this article is demonstrate & explain some of the basics so you can write shell scripts and work at the command line more effectively. See also our article on Aliases and Functions in bash for ways to customize your environment. I recommend highly the bash man page!!! Also the very good O’Reilly Nutshell book by Cameron Newham and Bill Rosenblatt, Learning the bash Shell.
I’m maintaining a Red Hat distribution on my machine srv-4 which I use to install other systems using kickstart via NFS. I downloaded a bunch of new RPMS from the Red Hat errata, but it’s a pain to copy them over into the RPMS directory because you must first remove the old one – the install will break if two versions of the same rpm are in the directory. This is an example of where we could do some basic shell scripting to make the job easier.
There are plenty of utilities out there to manage RPMS, including Red Hat’s own up2date, and others you can find on freshmeat.net. But shuffling these things around makes a great example for using bash.
[root@srv-4 RedHat]# pwd /opt/rh7.1/RedHat [root@srv-4 RedHat]# ls -l total 56 drwxr-xr-x 2 root root 40960 Aug 8 16:39 RPMS -rw-r--r-- 1 root root 92 Apr 8 21:04 TRANS.TBL drwxr-xr-x 2 root root 4096 Apr 8 20:41 base drwxr-xr-x 2 root root 4096 Aug 8 16:28 newrpms drwxr-xr-x 2 root root 4096 Aug 8 16:39 oldrpms
New packages from Red Hat are automatically downloaded into newrpms. They must then be moved into RPMS, the directory used by the installer. The old versions should be removed from RPMS and stored in oldrpms in case a rollback is necessary.
First we’ll work it out at the command line, then we’ll get it going in a script which can be run unattended.
[root@srv-4 RedHat]# cd newrpms [root@srv-4 newrpms]# ls gcc-2.96-85.i386.rpm gcc-g77-2.96-85.i386.rpm xinetd-2.3.0-1.71.i386.rp m [root@srv-4 newrpms]# for i in * > do > t=$(echo $i | sed 's/-[0-9]././g' | cut -f1 -d.) > echo $t >> ../names.tmp > mv ../RPMS/$t[-][0-9]*i386.rpm ../oldrpms/ 2>>../baddies.tmp > done [root@srv-4 newrpms]# cat ../names.tmp gcc gcc-g77 xinetd [root@srv-4 newrpms]# cat ../baddies.tmp [root@srv-4 newrpms]# ls | wc -l 3 [root@srv-4 newrpms]# ls ../oldrpms | wc -l 3
OK, everything looks ok. We have no errors, and there are the same number of old rpms as newrpms. Let’s go ahead and move the new rpms into the RPMS dir.
[root@srv-4 newrpms]# mv * ../RPMS/
Click here for the annotated script
Here are some other little tidbits that aren’t covered in our rpm update shell script. Consult the bash man page or the bash book for more detail.
special variables that are assigned from the shell’s arguments.There’s a lot more to this, read up on it.
[usr-3@srv-4 usr-3]$ cat myscript.sh #!/bin/bash echo "$0 is $0" echo "$1 is $1" echo "$2 is $2" [usr-3@srv-4 usr-3]$ ./myscript.sh arg1 arg2 $0 is ./myscript.sh $1 is arg1 $2 is arg2
evaluate arithemetic expressions & assign them to a variable:
[usr-3@srv-4 usr-3]$ let x='(4+5)-2' [usr-3@srv-4 usr-3]$ echo $x 7
increment a count:
[usr-3@srv-4 usr-3]$ let t=0 [usr-3@srv-4 usr-3]$ while [ $t -lt 5 ] ; > do > echo $t > let t=$t+1 > done 1 2 3 4
Can be used to read input from a file, line-by-line or from the command line in interactive fashion. It should be noted that working on input line-by-line is not one of bash’s strengths – if you must do this, the task you’re working on may not be very well suited for a shell script, you might want to use perl or c instead.
example reading from the prompt:
[usr-3@srv-4 usr-3]$ cat myscript.sh #!/bin/bash echo "how many hot dogs can you eat?" read ANSWER echo "wow $ANSWER is a lot!" example reading from a file: [usr-3@srv-4 usr-3]$ cat myscript.sh #!/bin/bash while read color do echo $color done [usr-3@srv-4 usr-3]$ ./myscript.sh < colors pink blue yellow green
-Coping with Quoting
escape character, escape a single character
$ rm p**p (will remove a file called p**p, not a file called poop,peep or pupp) also used for line continuation, escapes the carriage return.
” preserves all but $ ` ( and when followed by $ ‘ ” )
‘ preserves literal value of everything within
Now you can write some kick-a** shell scripts and function more efficiently at the command line. Remember, don’t do something by hand more than once! Write a script!