36979242 Shell Programming

28
{\rtf\ansi\deff0\ansicpg1252 {\fonttbl {\f0\froman times new roman;}} {\colortbl\red0\green0\blue0;} {\info{\author þÿ}} \jexpand\viewkind1\viewscale100 \paperw12240\paperh15840\margl666\margr133\margt666\margb173 \cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \f s24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\c f0\f0\charscalex100 { 1}\par\pard\li2626\r i0\sl-213\slmult0 \fs18\cf0\par\pard\li2626\ri0\sl-213\slmult0 \fs18\cf0\par\par d\li2626\ri0\sl-466\slmult0 \fs40\cf0\f0\charscalex100\b {Unit-7}\b0 \par\pard\l i1613\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1613\ri0\sl-533\slmult0 \fs40\cf0\ f0\charscalex100 {Shell Programming}\par\pard\sect\sectd\sbknone\pard\li1133\ri0 \sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\ li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-426\slmult0 \fs18\cf0 \f0\charscalex100\b {PROGRAMMING IN THE BOURNE AND THE C-SHELL}\b0 \par\pard\li1 133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-293\slmult0 \fs20\cf0\f0 \charscalex100 {You can use the Shel as a programming language. The C- Shel ha s al the usual language }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\chars calex100 {constructs like sequencing, looping, decisions, variables, functions a nd parameters. In this }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charsca lex100 {section we wil look at these abilities of the Shel , although regretful y not in complete detail.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\par d\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {To look closely at the C - Shel 's capabilities would require a block in itself. That is why as usual }\p ar\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {we wil only take a few portions in detail and leave you to the documentation for the rest. As wit h }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {any other pro gramming language, the key to mastering the C-Shel is practice. Keep writing Sh el }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {programs Wh enever needed and you wil soon feel comfortable with them.}\par\pard\li1133\ri0 \sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charsc alex100 {When you have written some complex Shel programs you wil realise that some UNIX utilities }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscale x100 {which you might have thought were useless, are actual y very important and useful. Sed is a good }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charsca lex100 {example of such a utility.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0 \par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Shel programs a re very often cal ed shel scripts. By the way a She,, is a program like any oth er, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {which means that there can be different shel s. Actual y there are some other popular shel s, of }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {which the Bourne shel and the Korn shel are quite likely to be available at your instal ation. The }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Bou rne shel was the first shel . in fact, and is sure to be there on your machine. }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult 0 \fs20\cf0\f0\charscalex100 {If you look at a UNIX machine, you can think of it as being composed of several layers. At the }\par\pard\li1133\ri0\sl-226\slmult 0 \fs20\cf0\f0\charscalex100 {lowest layer is the hardware which does al the ph ysical tasks and without which there would be }\par\pard\li1133\ri0\sl-226\slmul t0 \fs20\cf0\f0\charscalex100 {no computer and no LNIX. Above that is the UNIX k ernel which is the core of the operating }\par\pard\li1133\ri0\sl-240\slmult0 \f s18\cf0\f0\charscalex100 {system and does memory management, device handling and al the other mundane tasks needed }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\c f0\f0\charscalex100 {to make the hardware easily usable by us. The UNIX commands and utilities}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0 \sl-240\slmult0 \fs20\cf0\f0\charscalex100 {come next. At the top is the Shel w hich can be considered to be the outermost layer and which }\par\pard\li1133\ri0

Transcript of 36979242 Shell Programming

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 1/28

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 2/28

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 3/28

i1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {if you had mistakenly leftgaps while naming the files, you could not be sure that there were no }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {more files. To be sure, you would have to do an Is to look at the directory listing first. Then you }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {would have to keep issuing mv commands until you succeeded in moving al the files. Here you }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {would probably need to

keep checking the directory listing from time to time.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {It is much less effort if you use wild cards. Just say the fol owing afteryou have made the sub-}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {directory you want}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph??.C knapsack}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {The ? is a wild card character and can stand for any single character including itself, much like }\par\pard\li1133\ri0\sl-240\slmult0

\fs20\cf0\f0\charscalex100 {the. in vi. So cph??.C expands to cph fol owed by any two characters, fol owed by C. This is quite }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {likely al you need to say. If it does not work

, it can only be because you named some of the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {programs differently, thus invalidating our basic assumption, not because of a problem with wild }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {cards.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The ? metacharacter implies the existence of exactly one character in that position. So cph1.C }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {wil not be matched by the command above. You need to remember this. If, for example you had }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {named the files cphl.C, coh2.C, ..., cph10.C, cph11.C and soon, then the command.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph??.C knapsack}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {wil leave

any files from cph1.C to cph9.C in the same directory as before. You can move them }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {too with case}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph?.C knapsack}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100

{But what if your naming convention only started the filenames with cph and alowed any number }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100{of characters after that (this is quite common)? Is there no easy way out? Even

assuming a limit }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of 14 characters in the filename (some systems do not have a limit), and counting 2 fixed }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {characters at the end and 3 at the beginning, you are left with upto 9 charactersto look for in the }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {middle. So you can use the fol owing method}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100{% mv cph?.C knapsack}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph??.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph???.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph????.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph?????.C knapsack}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 4/28

3}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15

840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph??????.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph???????.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph?????97?.C knapsack}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% mv cph?????????.C knapsack}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0\fs20\cf0\f0\charscalex100 {While this is much simpler than looking at the directory listing and then issuing mv commands, it }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {entails some labour anyway. This was the time tosay}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {%mv cph*.C knapsack}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100

{You have now seen the * metacharacter, which matches any sequence of characters in that }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {position, including the situation where there is no character at al . So the * here matches from 0 to }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100

{9 characters (more if required), and those characters can be any character including the * itself, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {except a leading period.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {You cannot at this stage wonder how to put a ? or a * in a filename, except that in the Bourne }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {shel a command like}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ vi cph*.C}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {is not expanded unless there is at least one filename around which satisfies the expansion of the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command. So if there is a directory which does not have any file whose name starts with cph, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {then a filename cph*.C is created. where the * is taken literal y. In other cases, you can create }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {sucha file by}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% vi cph\\*.C}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100

{escaping the * with a\\ as usual. A? can be put into a filename in the same way. But it would be a }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {good idea to avoid such characters in filenames so that there is no confusion.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs20\cf0\f0\charscalex100\b {SIMPLE SHELL PROGRAMS }\b0 \par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-293\slmult0 \fs20\cf0\f0\charscalex100 {We spoke earlier about how we could use the C-Shel as a programming language. Before we }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {see how to write programs using al the capabilities of the Shel

, we wil look at some simple shel }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {scripts to il ustrate the concept.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Suppose you, khanz, are working on your cryptography project in a directory ~/prj/crypt/pkc/src }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {where your source files are located. This is where you are most of the time. But sometimes you }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {have to stray away from here to look at documentation which you have stored elsewhere, or to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {some other project you are working on. It is cumbersome to type out the whole pathname of this }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {directory to search it. Let us create a shel script in your home directory

to do the job. Use vi to }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\char

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 5/28

scalex100 {create a rile wd}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% cat wd}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Is ~/prj/crypt/pkc/src}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Now go to some distant directory like /usr/include/sys and type}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% wd}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Nothing happens, or rather you are told that wd cannot execute. This is because you do not have }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {execute permission on the newly created filewd (unless you have set the umask to al ow it). So }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-453\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

4}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {we need to acquire this permission, which is easy because we own the file}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% chmod 755 ~/wd}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Now you can try typing ~/wd to execute the file. You could also have tried}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% csh ~/wd }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {which would also have executed. We have looked at this in the discussion of the mail command, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {and we wil

look at in some more detail later.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Note that if you just type}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% wd}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {in a

distant directory, you wil not be able to execute the command. This is becausewhen the }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Shelis given a command to execute, it looks for the command in different directorie

s in a fixed }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {sequence. The first directory searched is the current directory, fol owed by /binand /usr/bin.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {These are only typical settings and can be control ed by you in a manner which wil be soon }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {explained. Since wd is not in any of these directories. UNIX does not find the command and }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {complains. Until you learn how to fix this,you can continue with ~/wd.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {If you consider it careful y, you wil realise that you have now created a UNIX command of your }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {own. If you give others execute permission on the file, anybody else could type wd and search }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {your directory.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {While that is probably not what you would want to encourage, you could create more general y }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {useful shel scripts presently. This is at the core of the UNIX philosophy of building on the work of }\par\pard\li1133\ri0\sl-226\slmult0 \

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 6/28

fs20\cf0\f0\charscalex100 {others. Once somebody has written a command, you do not have to write it again. But if you want }\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {to do something slightly different. you can, probably use the available command and use other }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {commands to modify its effect. We wil see examples of this by and by.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You have to be careful when you write general y useful shel scripts. While you can afford to be a }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {wee bit sloppy when you are writing for yourself, and can sometimes leave weaknesses in the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command because you know of them

and wil take care not to use the command in those }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {situations, you cannot release a command for public use so casual y. Most instal ations have a }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {set of shel scripts and programs in the usual programming languages available.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {These are local y developed or acquired programs which are found to be useful at that site. You }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {should learn

to use them to advantage before you try to write your own commands for some task. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Such utilities are usual y placed in /usr/local/bin. If you have special purpose utilities that are not }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {generalised enough to go there, you can col ect them in your directory tree in a place like ~/bin.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Let us now look at some of the pitfal s a novice might come across when writing his own shel }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {scripts. Suppose you want to have your Is command work like Is -al and you do not want to type }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {out the ful command every time. So in your home directory you can create a file Is}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% cat Is}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Is -al}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {and make it executable. Now when you try to look at the directory listing}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% Is}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-386\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100{

5}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0\fs20\cf0\f0\charscalex100 {you get a blank look from UNIX and you wil not need

to interrupt the command. This is because }\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {the command is cal ing itself in an infinitely recursive fashion. You wil therefore need to change }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {your command}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% cat

Is}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {/bin/Is -al}\par\pard\li1133\ri0\sl-213\slmult0

\fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {so that it cal s the real Is. That is how you can hope to get any work done, because your Is relies }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {o

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 7/28

n the system's Is command to get you the directory listing.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {This wil now work, but not if you try a command like}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% Is prj/crypt}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {You wil stil get the listing of your current directory. That is because we have rot given our Is the }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {ability to recognise command line arguments. We wil soon see how to do that. ntil then, our lsis }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {not going to

be very useful.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs20\cf0\f0\charscalex100\b {VARIABLES}\b0 \par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {We now come to the basic features of the Shel programminglanguage. Let us see how variables }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {can be defined and used in the C_ Shel . In the course of this discussion we wil solve many other }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {mysteries which we have been putting off til now, like

how to make UNIX recognise a command }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {in some directory, how to change the UNIX prompt, how to customise your environment when }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {you login and several other things.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100{It is easy to define and set a variable in the C-Shel and look at its value. For example, you can try}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set vehicle =bus}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {This creates a Shel variable cal ed vehicle and sets its value to "bus". To look at the value say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% echo $vehicle}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {bus}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {If we have another variable cal ed vehicle1 with a value car, we can say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% echo $vehicle and $vehicle1}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {bus and car}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0

\fs20\cf0\f0\charscalex100 {The echo command has been given three arguments here of which the first and third are shel }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {variables and the second is a constant string. The command dutiful y prints out the values of the }\par\pard\li1133\ri0\sl-240\slmult0

\fs20\cf0\f0\charscalex100 {variables and the constant is unchanged.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {But if you want to now define another variable adj to be "business", then you cannot say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set adj =$vehicleiness}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% echo $adj}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-466\slmult0 \fs24\cf0\f0\charscalex100

{ ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

6}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 8/28

sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Since there is no variablecal ed vehicleiness, this sets the value of adj to a nul string. You can }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {achieve the effect you want by enclosing the available variable in braces}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100

{% set adj=$ (vehicle\} iness}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% echo $adj}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {business}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {If a variable is to be set to a string containing spaces, then the string needs to be enclosed in }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {quotes, single ordouble}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set greeting = "How do you do"}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% echo $greeting}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {How do you do}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \

fs20\cf0\f0\charscalex100 {Once you have defined a variable you can freely use its value. So if you have said}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set Cat= "cat ~/.exrc"}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {then you can always print out your exrc file by

saying}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% $Cat}\par\pard\li1133\ri0\sl-213\slmult0\fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {set numberset tabstop=4}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {set terse}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Another way of setting Shel variables is by making them equal to the output of a command. To }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {use the output of a command in the Shel you have to put the command in theaccent grave, or }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100

{back quotes.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Similarly you could set a variable to the current directory}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set dir--'pwd'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% echo $dir}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {/usr/khanz/prj/crypt/src}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {We wil now see how to pass arguments to Shel

scripts so that they are not ignored when the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command is executed. You have seen how the private Is command you had created did not take }\par\pard\li1133\ri0\sl-240\slmult0\fs20\cf0\f0\charscalex100 {any arguments into consideration. The command was therefore not of much use. You wil now }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {learn to rectify this shortcoming. }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {In fact many of the other toy Shel scripts we have written so far are al but useless if we cannot }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {get them to accept arguments and act on them. For example the Cat command given as an }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {exercise would be much more useful if one could ask it to print the file ofone's choice in upper }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {case rather than some fixed file.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You can make a shel script refer to command line arguments by using the notation $n for the nth }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {argument

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 9/28

. Only 9 arguments can be so accessed. These are also cal ed positional parameters }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {because they

are referred to by their position on die command line instead of by name. The name }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of the shel

script itself can be referred to as $0. So you can write an improved version of your Is }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs24\cf0\f0\charscalex100 { ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {command}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% cat ~/is}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {/bin/Is -al $1}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

7}\par

\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {This version wil accept the first argument given to it. So ifyou say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% ~/Is /usr/khanz/prj/cryt/src}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {you wil get a long listing of al files in that directory. But

even this fails if you give a second }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {argument or more arguments. Try the fol owing command}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% ~/Is /usr/khanz/prj /usr/khanz/doc}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Now only the first argument is recognised and the second is ignored.

Wel , let us have an Is }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {which recognises 9 arguments. So we get into vi and change our command

to}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% cat ~/Is}\par\pard\li1133\ri0\sl-213\slmult0\fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {/bin/Is

-al $1 $2 $3 $4 $5 $6 $7 $8 $9}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {But what if there arc more than 9 arguments? Are we doomed to have only such a limited version }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of our Is? Fortunately in this case you can easily solve the difficulty by using the notation $* which }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {stands foral the arguments, whatever the number. This way we can get around the limitation of }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {being able

to handle only 9 positional arguments. Thus we now have a ful blown Is commandof }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {our own}\pa

r\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% cat ~/Is}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {/bin/Is -al $*}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {We can also find out the number of arguments by saying $#. This excludes $0, the name of the }\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {shel script itself. So you can write a simple command to count the number of arguments given to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {it. Such a capability is also useful when you want

to write production shel scripts which need to }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {take care of error checking. for instance, ensuring that the shel script works only if it is cal ed with }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {the proper number of arguments, or

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 10/28

even performing a different action depending on the number }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of arguments passed to it.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% cat count}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {echo $#}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% count apple boy cat dog elephant fish}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {6}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {There is also a shift command which has the effect of shifting its arguments such that each. }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {positional parameter gets the value of the next one, and the original value of the first parameter is }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {discarded. Using this facility you can deal with a situation where there are more that 9 positional }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {arguments. Let us see a simple example}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% cat showargs}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri

0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$1 = $1'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

8}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-266\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$2 = $2'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$3 = $3"}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {echo"\\$4 = $4'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$5 = $5'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$6

= $6'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100{echo "\\$7 = $7'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$8 = $8'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$9 = $9'}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$10 = $10"}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100

{The echo command can be given the -c argument to suppress dw printing of the new line }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {character, -n for inserting a new line character, -f for form feed and -t for tab characters. In the C- }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100

{Shel the -n option suppresses the printing of the new line. Any variable enclosed in double }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {quotes are substituted for their actual values, but anything in single quotes is

not altered. }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {If you want a character literal y within double quotes, you can use a backslash to escape it. Within }\par\pard\li11

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 11/28

33\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {single quotes you would not need the backslash but then you would not be able to get the values. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Quotes of one kind can be used to enclose quotes of the other kind. Now we can understand the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {output of showargs}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% showargs apple boy cat dog elephant fish girl house }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$1 = apple}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$2 = boy}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {$3 = cat}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {$4 = dog}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {$5= elephant}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$6 =fish}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {$7 = girl}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {$8 = house}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {$9 =inkpot}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$10=apple0}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {You can see that $10 has been interpreted as $1 fol owed by the lit

eral 0. To take care of this we }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {wil alter showargs (only the him lines are shown)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% cat showargs}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-280\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {...}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

9}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$9 = $90}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {shift}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {echo "\\$10 = $9*}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Now the output of the previous command changes to the fol owing}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$9 = inkpot}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$10=jug}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {There are some variables in the Shel which are predefined, which means that their values do not }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {have to be set by you. When you login those variables are created and set appropriately. }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {However many of them can be altered subsequently. You can see a list of al variables currently }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {defined together with their values by saying}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% env}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {printenv has the same effect. You should check out your environment with the env command. }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {You can easily make out the meanings ofmost of them because the names are suggestive of the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {meaning. Thus LOGNAME is your login name,

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 12/28

HOME is your home directory and so on.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You can also

use the set command to display the values of al variables set in the current shel . }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {For example the default C-Shel prompt is the percentage sign %, stored in the shel variable }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {prompt. This is the key to customizing your environment when you login, as we have alwaysbeen }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {promisingyou could.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {In the C-Shel every time you login, UNIX looks for a file in your home directory cal ed ".login". If }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {this file exists then , commandsin that file are executed before you are presented with your first }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {system prompt. 'Mere is a corresponding file which is executed when you log out of the system. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {ibis file is cal ed ".logout".}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Suppose you usual y work in Your /usr/khanz/Prj/crypt/c++/src directory. You would like to be }\par\pard\li1133\ri0\sl-240\slmul

t0 \fs20\cf0\f0\charscalex100 {placed in this directory automatical y every timeyou login. Al you have to do is to put the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {fol owing line in your .login file}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {cd prj/crypt/c++/src}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Since you wil anyway reach your home directory. we have given a relative pathname to reach the}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {desired directory. If you want your UNIX prompt to give you the number of the command you wil}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {be executing, you can say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {set prompt=\\!\\%\\}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {The exclamation mark stands for the command number and we escape it toprevent it from being }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {evaluated immediately, which would make the prompt constant. Now you seea prompt like}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {1% pwd}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {/usr/khanz/pd/crypt/c++/src}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {2%}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-386\slmult0 \fs24\cf0\f0\charscalex100 { ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

10}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Every time

a command is executed the command number increases by one and this shows up on}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {your prompt. Commands separated by semicolons are considered to be one command, as you }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {know.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {There are some other convenient features which can be set up for a pleasing environment. Of }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {course these are a matter of individual taste, so we wil talk of those

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 13/28

done by most people. You }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {can always choose what you feel congenial for yourself. If you say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set ignorecof}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {then you

wil have to " out "exit' or "logout in order to terminate your login session,a mere ^D wil }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {result in a message}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Use "logout" to logout}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs18\cf0\f0\charscalex100 {This is useful to prevent accidental log outs because ^D can get typed by mistake while it is much }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {more unlikely you wil " a ful word when you do not need it. Another safety feature is to say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% set noclobber}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs18\cf0\f0\charscalex100 {If this variable is set then an operation which would otherwise overwrite an existing file silently wil }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {refuse to do with the message}\par\p

ard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {file exists}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Both these variables need only be set, and no values need to be put in them. The C-shel }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {distinguishes betweenvariables whose value is nul and those not defined at al .}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {A very convenient feature Of the C-Shel (this is absent in the BourneShel ) is the facility of a }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command history. If you set the variable history then the last commands you typed in can be }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {executed very easily without your having to type the complete commandin}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% set history=100}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {wil al ow you to access dw last 100 commands you typed. If you want to see al of them, just say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% history}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {and the last 100 commands wil be displayed. You can set history to a smaler value of about 20, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {this is probably sufficient most of the time.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100

{If history is set, you can run a Previous command in two ways. You can say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {%!56}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {and the 56th command

of your session (not 56th in the current history) wil be executed. This }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {includes al commandline arguments, redirections, pipes and al other special characters it might }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {have contained. Usual y when you want to repeat some command you do not know its number, }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {but you of course knowwhat the command was. Let us say you ran a longish sed command to }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {perform some action on a file

and now you need to do it again after some change has occurred to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the input. You need to say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0\fs20\cf0\f0\charscalex100 {% !sed}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {and the last command starting with sed wil run. You do not have to give the whole word sed. any

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 14/28

}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {number of characters which make the command unambiguous wil do. So if you have not run any }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0\fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

11}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {command starting with se after youran sed, you can say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {%!se}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {and if you have not run any command with s itself, you could have abbreviated it stil further. But }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charsc

alex100 {remember that the last command is the one that wil be run. If there were a command like sedate }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {and if you had run it after sed, then the above abbreviated commands would have run it instead }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of sed.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {There are ways of editing the command before running it but it is usual y simpler to retype it again }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {in that case. Also the abbreviated command can be used to run another command containing it }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {like this}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {34% sort datafile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {....}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {48%!34 newfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {sort datafile newfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {There is one aspect of the Shel which we have mentioned earlier but which needs elaboration. }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {Whenever a command is executed it does so in a child shel which inherits the environment of the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {parent shel . If you want variables you have set to have effect in child shel s as wel , you need to }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {say setenv rather than just set. Otherwise those

variables wil not be passed onto child shel s. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {You can easily try this out.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Another thing is that you cannot make a change to your login file, run login and have the changed }\par\pard\li1133\ri0\sl-240\slmult0 \fs18\cf0\f0\charscalex100 {environment. This does not mean that the commands are not run. The point is that they are run in }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {a child shel and as soon as the command terminates, you are back in the parent shel where }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {there is no effect of anything that happens in a child shel . Theenvironment is passed downwards }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {to child shel s but cannot be passed back to parent shel s. Tomake a change to your login and }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {have it take effect immediately, you should say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% source login}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This runs the login fi

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 15/28

le exactly as if you had typed out each command at the prompt instead of }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {executing the commands

in a child shel . To be precise, the source command temporarily (for the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {duration of the command) redirects the standard input of the shel to come from the file instead of }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {from the terminal. This command can of course be given any shel script as an argument and is }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {not confined to login.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs18\cf0\f0\charscalex100 {One more feature which is sometimes useful in

the C-shel is the repeat command. You can run a }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command several times repeatedly by saying}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% repeat 17 echo hel o}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {and you wil find that the echo is executed 17 times.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100

{You can use the alias feature of the C-shel to abbreviate commands (strictlyto give them another }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscale

x100 {name). Thus if you frequently use Is -al, you can say something like}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {% alias 11is -al}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs24\cf0\f0\charscalex100 { ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

12}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Now whenever youwant to use Is -al, just say l and you wil get the same effect. You can give }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {arguments to land they wil be taken as additional arguments to Is -al, the actual command. To

}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {turn this feature off, just say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% unalias 11}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Usual y such aliased commands are placed in one's .login file so that they are in effect }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {automatical y as soon as one logs in.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-386\slmult0 \fs20\cf0\f0\charscalex100\b

{PROGRAMMING CONSTRUCTS}\b0 \par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-293\slmult0 \fs20\cf0\f0\charscalex100 {So far the shel scripts we have written have been nothing but a sequence of commands which }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {we could very wel have given from the system prompt itself in most cases. They would have }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {been useful but not very much

so, if the capabilities of the Shel were confined to setting variables }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {and printing their values.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {What makes the shel Powerful is that we can use it as a programming language. it has al the }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {constructs needed to write a program, and in this section we shal look at them.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 16/28

par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {While the C-Shelis very convenient to use on the command line because of its greater set of }\p

ar\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {features suitablefor interactive use, the Bourne shel is sometimes more convenient in some }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {ways when you want to write a shel script. For this reason in this section we wil discuss mainly }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the Bourne Shel

and wil give the C-Shel features sometimes, because of lack of space. }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {As always, you are regretful y referred to the UNIX documentation for the details of how to }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {program in the C-shel . But remember that even if you use the C-shel for interactive commands, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {you can always run a Bourne shel by giving a: by itself on

the first line of the shel script.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {This is also the default shel used for shel scripts. So even if you omit the: the script wil

be }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {assumed tobe a Bourne shel script and wil be run as such by default. You can run a C-sh

el }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {script by putting a # instead of a: on the first line.}\par\pard\li1133\ri0\sl-213\slmult0\fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {In thefol owing examples you can distinguish between the Bourne rind the C-shel scripts by the }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {prompts used ($ for the Bourne shel and % for the C-shel ), and by the: or the # inthe scripts.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Let us first look at the looping constructs available. There is a for loop which works like this in the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Boume shel , which has a default $ prompt}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$ cat mkupper}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {for i in 'Is'}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {tr [a-z]"[A-Z]' $i $i.up}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The C-shel version Of the

sane script wil be like this}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {% cat mkupper}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {#}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {foreach i ('Is')}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {tr '[a-z]' ' [A-Z]' $i $i.uP}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {end }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-466\slmult0 \fs24\cf0\f0\charscalex100 { ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

13}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0

\fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This script wil change every file in the current directory to upper case and write it

out with the .up }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {extension. The i is a variable we use to effect to our plans, and it serves as a loop variable. The Is }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command can have several values and the loop is executed for each of

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 17/28

the values in turn. For }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {every value, the file is converted to upper case and written out with a

.up" extension.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {When al the files have been processed, the loop terminates. We can write another version of this }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {script which wil convert onlythe flies specified as arguments to it into upper case.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$ cat mkupper.arg}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {for i in $*}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {tr '[a-z]' '[A-Z]' $i $i.up}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Here we can give the script any number of arguments and every file we specify wil be converted }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {into upper case. Actual y in this

case we can omit the in and the first line can be}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {

for i}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {which wil work just as the previous line. One can also execute loops with the while or until }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {constructs, which have the usual meanings.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ cat mkupper.1}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {while test $# -gt 0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {tr '[a-z] ' ' [A-Z]' $1 $ I.up}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {shift}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Here the while loop is performed as long as there are some arguments left. The tr operation is }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {done only on the first argument everytime. The shift then renumbers the arguments and throws }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {out the first argument (which has already been dealt with). When there are no arguments left the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {loop terminates. The C-shel has itsown version of the while loop.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The until loop is exited only when the condition becomes true. This construct is not available in }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the C-shel , butyou can get around that quite easily by negating the condition of a while loop.Let }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {us look atthe version with this loop construct}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$ cat mkupper.2}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {until test $# -eq 0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {tr '[a-z]' '[A-Z]' $1 $1.up}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {shift}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Now the loop is terminated when the number of arguments is 0. Of course since wehave }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {changed the condition to be tested, the effect of this is the same as in the while loop case.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {In the looping examples above, we have been using the test operation. which can be used in the }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Bourne shel to test various conditions. lie op

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 18/28

eration returns a 0 if the test is passed and a non }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {zero value otherwise. We wil quickly describe the conditions which can be tested. Let us first look }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {at the relational operators on positive or negative integers. You can say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

14}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-266\slmult0 \fs20\cf0\f0\charscalex100 {test a -gt b (for checking if ab)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {test a -ge b (for checking if a = b)}\par\pard\l

i1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs18\cf0\f0\charscalex100 {test a -eq b (for checking if a = b)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {test a -ne b (for checking if a != b)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {test a -It b (for checking if a b)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {test a -le b (for checking if a b)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {In the translation examples above, we have used this numeric test to stop the loop when there }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {are no arguments left. Suppose there wereno arguments given to the command mkupper when it }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {was run. One could exit silently, or print an

error message, or use the standard input in such a }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {case. The examples given al exit silentlyif there are no arguments. Let us see how to change }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {this behaviour.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs20\cf0\f0\charscalex100 {$ cat mkupper.3}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {if test $# -eq 0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {then echo "No files to translate!"}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {exit}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {fi}\par\pard\li1133\ri0\sl-226\slmult0

\fs20\cf0\f0\charscalex100 {while test $# -gt 0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {tr'[a-z]' '[A-Z]' $1 $1.up}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {shift}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {The beginning of the script introduces to the if statement, which is how a decision can be made in }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {the shel . We wil look at this statement and its variants a bit later. The fl delimits the statements }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {to be performed if the condition is true. This script wil tel you if are no files to translate and wil }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {put you back to the shel prompt if that happens. You can now easily write a script which takes }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {input from the standard input if no arguments are supplied to the command when it

is invoked.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {We can now look at some of the tests t

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 19/28

hat can be performed on files. Here you can use ! as the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {negation operator to check for the inverse of a condition.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {test -s filename (does a non-empty filename exist?)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {test -f filename (is filename

an ordinary file?)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {test -d filename (is filename a

directory?)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {test -r filename (is filename readable?)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {test -w filename (is filename write able?)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {The tests for reading and writing are for the user running the script, that is, you can find out if you }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {can read from or write to the file in question.

Using these tests, we can make our script more }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {robust by checking if the files given as arguments exist}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-2

40\slmult0 \fs20\cf0\f0\charscalex100 {$ cat mkupper.4}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

15}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {if test 5# -eq 0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {then echo "No files to translate!"}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {exit}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {fi}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {while test $# -gt 0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {if test -s $1}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {then iftest -f $1}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {thentr'[a-z]' '[A-Z]' $1 $1.up}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {fi}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {fi}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {shift}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Here we have used two if statements within .the while loop to check for

the existence of each file }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {given as an argument to the command. You should expand this scriptto print an appropriate error }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {message whenever needed. Notice that the actual action we are performing is confined to the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {one line tr command. It is the error checking that is now taking upmore and more of the script. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {This is in keeping with what happens in most programs, where error

checking takes up a large }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {part of the production version of any software.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {You can also compare two character strings as fol ows}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {test a = b (is string a the same as string b?)}\par\pard\li1133\ri0\

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 20/28

sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {test a != b (are the strings different?)}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You can also use test -z which is true if a string is nul , and test -n which is true if the string is not }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {nul . Also, test by itself, if fol owed by a string, checks if the string exists. You should now rewrite }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the previous script to check for the absence of an argumentusing the appropriate form of the test }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {operation.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You can combinetwo tests with -a for an and operation (true if both the tests pass) or -o for an or }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {operation(true if either of the tests pass). This can be used to rewrite the scripts above with only }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {one

if statement.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The if statement itself is the sameas in conventional programming languages. If the condition }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {fol owing the if keyword is true the

statements that fol ow are executed. The body of the if is }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {terminated with a fi. Suppose you want to write a script that wil take three arguments. The first }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {two should be filenames that exist and the third is to be a new file that wil hold the concatenation }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of the upper case versions of the first two files. We thus need to ensure that the first two }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {filenames exist and the third does not.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The if statement can have an else part which is executed if the condition fol owing the if is not }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {true. In such a case the then is delimited by the else and the whole statement is delimited by the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {fi. ]be else if construct is also available and can be combined as an elif keyword. In the C-Shel , }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the delimiter is the keyword endif and you can give any number of else parts.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100

{$ cat Concat}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {if test $# -ne3}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {then echo "Usage: $0 in-fi l in-fl2 ou-fl"}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {exit}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100

{elif test! -s $1 -o ! -f $1}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {then echo "Invalid filename $ 1}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {exit}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

16}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100{elif test! -s $2 -o ! -f $2}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {then echo "Invalid filename $2'}\par\pard\li1133\ri0\sl-226\slmult0

\fs20\cf0\f0\charscalex100 {exit}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {clif test -s $3 -o -f $3}\par\pard\li1133\ri0\sl-226\slmult0 \

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 21/28

fs20\cf0\f0\charscalex100 {then echo "$3 exists"}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {exit}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {else tr '[a-z]' '[A-Z]' $1 tmp1}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {tr '[a-z]' '[A-ZI' $2 tmp2}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {cat tmp1 tmp2 $3}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {rm tmp1 trnp2}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {fi}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The break and continue statements are available with loops to come out of the loop and go back }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {to the beginning of the loop respectively.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {We can also put comments in the Boume Shel by using a #. Al statements on a line fol owing the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {# including the # itself are ignored by the shel during execution. In complex shel scripts it is a }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {good idea to include comments explaining what the script does and how it works.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0

\fs20\cf0\f0\charscalex100 {In the example above we used a multiple if statemen

t. In some situations it is more convenient to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {use the case statement which is il ustrated below. The example is a trivial one but does show how }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the statement works}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$ cat showcase}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {case $2 in}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-320\slmult0 \fs20\cf0\f0\charscalex100 {upper) tr '[a-z]' '[A-Z]' $1 $I.UP;;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {lower)

tr '[A-Z] " [a-z]' $1 $ 1.low;;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {*) echo "Invalid option';;}\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {esac}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This script takestwo arguments. The first is a filename which is converted into upper or lower }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {case depending on

the second argument The value of the second argument is checked against }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the strings upper andlower. These strings are delimited by a right parenthesis character). After }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {this is the body of

statements that wil be executed if a match is found. The shel metacharacters}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {can be used asstrings to match against. The whole case statement is terminated with a esac and

}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the action foreach option is ended with two semicolons.}\par\pard\li1133\ri0\sl-213\slmult0 \

fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Now youshould try the fol owing variation of the script}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$cat showcase. 1}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {case $2 in}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {*) echo "Invalid option";;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {upper) tr'[a-z]"[A-Z]' $1 $1.up;;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {lower) tr'[A-Z]"[a-z]' $1 $1.low;;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {esac}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This is the same as the earlier one except that the * now appears first in the list

of strings to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {check against. Since any string wil match this, this is the action that wil be

taken every time. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Thus it is the first match found which is executed in a case statement. So the order in which you }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscal

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 22/28

ex100 {write the matches in the body of the case is very important.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-346\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

17}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100\b {INTERACTIVE SHELL SCRIPTS}\b0 \par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-293\slmult0 \fs20\cf0\f0\charscalex100 {So far we have only looked at shel scripts which havenot required an interaction with the user }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {once started. But the power of the shel does not stop at the constructs we have seen so far. It is }\par\pard\li1133\ri0\sl-226\slmu

lt0 \fs20\cf0\f0\charscalex100 {possible to take input from the user and take further action depending on it. You can thus write }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {interactive programs.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {To pass user input to a command inside a shel script, we can fol ow the command with the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {notation &0. Although this is not necessary and user input wil usual y get passed to the command }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {inside the script, this notation ensures that this wil happen. Thus if in ashel script it is necessary }\par\pard\li1133\ri0\sl-226\slmult0 \fs18\cf0\f0\charscalex100 {to cal up vi in read only mode on some files (to al ow the user to examine them) you wil want that }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the user be able to use the view commands on those files. For this put the line which cal s up vi }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {like this}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {view $* &0}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {If you only want to accept input from the terminal directly for the shel program, you say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {read x}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {and whatever you type wil get assigned to the variable x.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {In one read statement you can have several variables to which you can assign values. The first }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {response is assigned to the first variable, the second

response to the second variable, and so on. }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-266\slmult0 \fs20\cf0\f0\charscalex100 {Responses are delimited by white space but a new line does the assignment. If there are too }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {many responses, al the extra responses gointo the last variable. Using these features you can }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {write a menu driven shel program to perform some tasks interactively. As you have seen, UNIX }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {commands are cryptic and do nor have a helpful user interface. You could write a menu driven Is }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {program, for instance. Let us cal it dir.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ cat dir}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {echo " 1 for long listing"}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {echo "2 for stream list'}\par\pard\li1133\ri0

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 23/28

\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {echo "3 for single column list"}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {echo "Enter your choice \\c"}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {read x}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0

\fs20\cf0\f0\charscalex100 {case $x in }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {1) Is -1 $*;;}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {2) Is -m $*;;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {3) Is -1 $*;;}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {*) echo "Invalid choice"}\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {esac}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This script has along way to go before you could release it as a useful utility for beginners, }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {though. There isno error checking beyond looking for a correct choice. You can try making this a

}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {bit more robust. For instance, if the user gives two input options, what wil happen?}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This seems like a good place to be talking of redirection.As you have seen in the introductory }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\

cf0\f0\charscalex100 {unit of this block, you can redirect the standard output of a command to another device or file. In }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the C-shel which we had been looking at them, a command like}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% Is -1 dir file}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 { ACME/GulshanSoni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

18}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {redirects thestandard output to the rile specified, dirfile in this case. 'Me standard error.

which is }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {not being redirected, is sent to the terminal screen as usual. To send the standard error also to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {error file we have to say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% Is -1 &error file}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Here both the standard output and standard error are sentto error file. The task of sending the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {standard output and standard error to different files is

slightly more complicated, as we have to }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {use sub-shel s for this. Enclosing any command in parentheses executes that command in a sub-}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {shel and as soon as the command terminates you are back in the parent shel . We can thus }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {redirect the standard output to dirfile and the standard error to errfile at the same time as fol ows}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {% (Is -1dirfile) &errfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {In the Bourne shel , on the other

hand. things are much more straightforward. To redirect the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {standard output alone, say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$Is -1 dirfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\c

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 24/28

f0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {This sends thestandard output to dirfile and the standard error to the terminal, as usual. To}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {redirect the s

tandard error, say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ Is -1 2 dirfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Now the standard output wil appear on the terminal and the standard error wil get redirected. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {This is because in the Bourne shel you can specify the file descriptor to be redirected by placing }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {it before the sign. The standard input is assigned to filedescriptor 0, the standard output to 1 and }\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {the standard error is assigned to file descriptor 2automatical y by UNIX. It should now be easy for }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {you to redirect the standard output and the standard error of a command to different files.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ Is-1 dirfile 2 errfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This command sends the standar

d output to dirfile and the standard error of the same command }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {to errfile. To redirect both ofthem to the same file you wil need to learn the idiom}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ Is -1 dirfile 2&1}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {which sends the standard error to the same place as the standard output}\par\pard\li1133\ri0\sl-213\slmult0

\fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {You have already seen in the first unit that in UNIX every device is actual y treatedas a file. We }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {wil look at this concept in more detail in the next unit, but here let us see the behaviour of a }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100

{special device file in UNIX, cal ed the nul device. This is available in thedevice directory just as }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {other devices are. Anything written out to the nul device simply disappears, and it is thus an }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {infinite sink. Trying to read from the nul device always results inan end of file. So if you want to }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {just discard the standard output, you just redirect it to the

nul device.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ Is -1 /dev/nul 2 errfile}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {This wil throw away the output of the command but wil save

the error messages in errfile. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Likewise, to discard the error messages but save the output, you could say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ Is -1 dirfile 2 /dev/nul}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You now know how to suppress al output from a command, but why

would one want to do that? }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Possibly if the command did perform some operations on a device ordisk file and you want it to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {work silently without showing anything on the terminal.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 25/28

19}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-266\slmult0 \fs20\cf0\f0\charscalex100{$ mv file1 file2 /dev/nul 2&1}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {wil do the move without any terminal output even if there are error messages from it. This is nota }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {good examplethough, for the command does not write to the standard output.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-293\slmult0 \fs20\cf0\f0\charscalex100\b {ADVANCED FEATURES}\b0 \par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-293\slmult0 \fs20\cf0\f0\charscalex100 {Let us now look

at a few capabilities of the shel programming language which you could consider }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {somewhat advanced. First we wil learn to do arithmetic. This can be done with the expr }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {command}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ expr 2 + 3}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {5}\par\pard\li1133\ri

0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Every number and operator is a separate argument to the expr command.So al of them have to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {be separated by spaces. If you do not do so, you wil get an error. Thecommand works only on }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {positive or negative integers. You can use the operators +, -, * for multiplication, 1 for division and }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {% for the remainder or modulo operation. Let us write a shel script to find the average of the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {numbers entered.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$ cat average}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {:}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {total=0}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {count=$#}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {for i}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {do}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {total='expr $total + $i'}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {done}\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {avgl ='expr $total 1 $count'}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {avg2='expr $total % $count'}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {avg2='expr $avg2 \\* 100 1 $count'}\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {echo "The average is $avgl.$avg2"}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {We initialise the variables total and count and compute the total by adding the value of each }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {argument until there are no more arguments. Since we want a somewhat more accurate average }\par\pard\li1133\ri0\sl-226\slmult0

\fs20\cf0\f0\charscalex100 {than to the nearest integer, we get the result to two decimal places in a roundabout fashion.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {We first

find the integer part in avg 1. To find the decimal part, we find the remainderafter the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {divi

sion, multiply it by 1 00 and divide it by the number of entries. This gives usthe digits after the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {decimal point. We then print out the answer by printing out both the variables separated by a }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {decimal point.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Note that the * operator has to

be escaped with a backslash \\ otherwise it would have the special }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {meaning of al the files in

the directory to the shel . The expr command has some more }\par\pard\li1133\ri

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 26/28

0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {capabilities which we wil not discuss here.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {Let us now look at another feature of the

shel , that of trapping interrupts and taking some action }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {depending on them. We wil il ustrate this with a simple example. Suppose you have written a }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {shel script which interchanges the names of the two files given to it as arguments. That is, if }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {there are two files cal ed chicken and egg, then}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ interchange chicken egg}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-306\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0

\charscalex100 { 20}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {renames chicken to egg and egg to chicken. As a programmer you wil realise that to do this you }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {need to use a temporary file. So abare bones script (without any precautions or error checking) }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {to do the job wil look like this}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {$ cat interchange}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {mychicken tmp}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {my egg chicken}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {my tmp egg}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {There is a fair amount of checkingthis script needs to do in order to be useful. The files must both }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {exist and there should not already be a file cal ed tmp. Assuming that these things are taken care }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {of, what happens if theuser breaks the script in between? Depending on the actual instant when }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {this is done, you wilhave a different situation, but certainly the effect you wished for wil not have }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {occurred, for

one of the files wil be named wrongly and you wil have a tmp file lying around. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {What you want in this case is a way to prevent the user from interrupting the script until it is }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {complete.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0

\fs20\cf0\f0\charscalex100 {In other, more realistic situations one uses temporary files to hold temporary results. These files }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {are deleted in the script after they are no longer needed. If your script is interrupted you would not }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {want these files to be lying around.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0\fs20\cf0\f0\charscalex100 {The shel has a command cal ed trap which al ows you

to achieve what you want. If you want to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {prevent your script from getting interrupted by the break key, you can say}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {trap " 2}\par\pard\li1133\ri0

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 27/28

\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {The quotes are the first argument to the trap command, which holds thecommand or commands }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {(separated by;) to be executed whenever the script receives any of the signals specified by the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {signal numbers in the subsequent arguments. You can look at the signal numbers and their }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {meanings for your system by examining the file "/usr/include/signal.h". A signal

gets sent to your }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {process wil result in the action you asked for. Here since there is no command specified. the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {effect wil be to do nothing when the shel script receives the signal number 2, which is sent by }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the break key. To remove a temporary file you create, you can say instead}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {trap 'rm -f tmp$0$$ 2/dev/nul ; exit'2 15}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$$ stands for the current process number and tmp$0$$ is a reasonable way of almost ensuring }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\

f0\charscalex100 {that the name of the temporary file you create wil not conflict with any other existing filename. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {Signal number 15 is the default kil signal sent to a process when you kil it. However note that }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {signal number 9 is the kil signal which cannot be caught or ignored, and so it is no use giving }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {signal number 9 as one of the signals in your list.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0\fs20\cf0\f0\charscalex100 {In the C-shel interrupts are handled differently and you should consult the documentation for }\par\pard\li1133\ri0\sl-226\slmult0\fs20\cf0\f0\charscalex100 {details.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {One more useful feature is the ability to give the input to a command which actual y takes its

input }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {from thestandard input normal y. You already saw how you can ensure that if any commandin }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the shel s

cript needs to take some input from the standard input you can supply that inputfrom }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {the keybo

ard just as you would have done if the command had been run from the terminal. }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0

\fs20\cf0\f0\charscalex100 {But that is not always what you want or need. Sometimes what is more important is to pass fixed }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {input to a shel command. For example you might want to write a shel script which can be cal ed }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {with a filename argument, and which locates anddeletes al lines containing the word specified }\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-373\slmult0 \fs24\cf0\f0\charscalex100 {

ACME/Gulshan Soni}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\sect\sectd\sbkpage\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\margtsxn666\margbsxn173\cols2\colno1\colw2280\colsr-0\colno2\colw9160\pard\li1133\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {Unit-7}\par\column\pard\li0\ri0\sl-333\slmult0 \fs24\cf0\f0\charscalex100 {

21}\par\pard\sect\sectd\sbknone\pgwsxn12240\pghsxn15840\marglsxn666\margrsxn133\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {as the second argument. You already know how to do this in ed interactively. But how do you }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {give this input in the script itself?}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {T

8/8/2019 36979242 Shell Programming

http://slidepdf.com/reader/full/36979242-shell-programming 28/28

o il ustrate this with a simple example, let us take up the case where you wantto give a }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {message if a person gives the wrong number of arguments. You could use echo, but letus do }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {this with

cat instead.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {if test $# -ne 4}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {then}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {cat < this}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {What a stupid mistake}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {this}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {fi}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {The feature shown here is cal ed a heredocument and 'S introduced by the notation <. The word }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {immediately after the < is a label, andeverything upto the first occurrence of that label first thing }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {on a line by itself is taken to

be input to the cat command. So you can emped input for your }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {command in the shel script itself. It should be clear that you cannot use this facility with }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {commands that do not read from thestandard input.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {You should now be able to write a shel script that does the things we had talked of in the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {introduction to here documents. The only part which needs to be done careful y is the input to the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {ed command.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Before we end this unit, let us talk briefly about how to debug shel producers. Although as }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {experienced programmers you wil not find it difficult to figure out wherethe error lies by using the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {eco command judiciously, you could find the facilities of the shel

useful. For example you can run }\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {a file with the v option for vebose output, wherein each command is printed and then executed. }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {This is like having an echo command after every line.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-240\slmult0 \fs20\cf0\f0\charscalex100 {$ sh - v Concat}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-253\slmult0 \fs20\cf0\f0\charscalex100 {Another option

is -x, where every command line is shown with a + sign at the beggining, and the }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {values of the

variables before and after the command are printed. To be safe you can decide to }\par\pard\li1133\ri0\sl-226\slmult0 \fs20\cf0\f0\charscalex100 {use the - n (noexecute) option, where the commands are read but not executed.}\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0

\fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-213\slmult0 \fs18\cf0\par\pard\li1133\ri0\sl-426\slmult0 \fs24\cf0\f0\charscalex100 { ACME/Gulshan Soni}\par}