<?xml version="1.0" encoding="ISO-8859-1"?><html xmlns="http://www.w3.org/1999/xhtml" xmlns:xh="http://www.w3.org/1999/xhtml" xmlns:axle="http://www.cs.odu.edu/~zeil/axle" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ns0="http://www.cs.odu.edu/~zeil/axle" mode="ignore" ns0:xlinkuri="open/unix.dbk" ns0:xpath="/html" ns0:page="unix" foo="0 " ns0:last="/cocoon/~cs252/open/unix/section-8.2.html"><head><title>An Introduction to Unix</title><link type="text/css" href="_axle/docbookstyle.css" rel="stylesheet"/><link type="text/css" href="_axle/cppformat.css" rel="stylesheet"/><link type="text/css" href="_axle/overrides.css" rel="stylesheet"/><script src="_axle/docbook.js"/><link href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/section-8.html" title="Prev" rel="prev"/><link href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/section-8.html" title="Up" rel="up"/><link href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/unix.html" title="First" rel="first"/><script>function gotoNext() {}
function gotoPrev() {top.location.href="/cocoon/~cs252/open/unix/section-8.html";}
function gotoUp() {top.location.href="/cocoon/~cs252/open/unix/section-8.html";}
</script><xhtml:link xmlns:xhtml="http://www.w3.org/1999/xhtml" rel="stylesheet" href="_axle/navigation.css" type="text/css"/><xhtml:script xmlns:xhtml="http://www.w3.org/1999/xhtml" src="_axle/navigation.js"/></head><body><table width="100%" class="navigationBar"><tr class="navigationBar"><td width="5%" class="navigationBar"><a class="navigationBarArrow" title="First" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/unix.html"><img class="navigationBar" src="_axle/first.gif" alt="First"/></a></td><td width="5%" class="navigationBar"><a class="navigationBarArrow" title="Prev" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/section-8.html"><img class="navigationBar" src="_axle/prev.gif" alt="Prev"/></a></td><td width="5%" class="navigationBar"><a class="navigationBarArrow" title="Up" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/section-8.html"><img class="navigationBar" src="_axle/up.gif" alt="Up"/></a></td><td class="navigationBar"/><td width="5%" class="navigationBar"><a class="navigationBar" title="CS252 Home" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/directory/announcements.html"><img class="navigationBar" src="_axle/home.gif" alt="CS252 Home"/></a></td><td width="5%" class="navigationBar"><a class="navigationBar" title="discuss this page" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/forum/getXPath/open/unix/section-8.2.html"><img class="navigationBar" src="_axle/forum.gif" alt="discuss this page"/></a></td></tr></table><br/><script type="text/javascript">
checkForAnchorOnOtherPage('section-1','unix');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('mainmini','mainmini');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-1.1.1','mainmini');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('displays','mainmini');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('networks','mainmini');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('taleof2','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-1.2.1','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('pcrev','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref1','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref1_live','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref2','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref2_live','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote1','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote2','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('mswin','taleof2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('reflections','reflections');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref3','reflections');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref3_live','reflections');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote3','reflections');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('ssh','ssh');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref4','ssh');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref4_live','ssh');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('puttyConnect','ssh');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('sshConnect','ssh');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote4','ssh');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('login','login');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('termtypes','termtypes');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref5','termtypes');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref5_live','termtypes');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote5','termtypes');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-1.7','section-1.7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-1.8','section-1.8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.1','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref6','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref6_live','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref7','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref7_live','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('basicFileCmds','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref8','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref8_live','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote8','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('cmdlist','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('session','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('rlogin','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('filemanip','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('cdcmd','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('findcmd','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('lsa','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('lsF','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('pwdcmd','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('textmanip','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('catcmd','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('morecmd','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('printing','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote6','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote7','section-2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.2','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref9','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref9_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('paths','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref10','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref10_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote10','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('specialChar','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('cmdpatterns','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref11','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref11_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('wildcards','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref12','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref12_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote12','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('regexp','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('grepregexps','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref13','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref13_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref14','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref14_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote13','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote14','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('sedregexps','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref15','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref15_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref16','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref16_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote15','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote16','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote11','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('quoting','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref17','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref17_live','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote17','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote9','section-2.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.3','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref18','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref18_live','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('redirect','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('piping','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xargs','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('find','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote18','section-2.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.4','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.4.1','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref19','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref19_live','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote19','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.4.2','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref20','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref20_live','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote20','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('umask','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-2.4.4','section-2.4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-3','section-3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('vim','section-3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref21','section-3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref21_live','section-3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-3.1','section-3.1');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-3.2','section-3.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-3.3','section-3.3');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('markregion','markregion');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref22','markregion');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref22_live','markregion');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote22','markregion');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-3.5','section-3.5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-3.6','section-3.6');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote21','section-3.6');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.1','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('twin','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('icewin','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('starwin','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('connections','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('runningx','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref23','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref23_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('launchTheServer','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('creatingsession','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.2.1.2','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.2.1.3','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref24','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref24_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote24','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.2.1.4','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref25','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref25_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote25','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('launchClient','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref26','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref26_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('launchViaSsh','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref27','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref27_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote27','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('launchViaPutty','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref28','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref28_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote28','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xlaunch-sessions','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xwin32-sessions','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref29','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref29_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote29','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote26','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote23','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.3','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xappl','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xtrouble','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('cannotOpen','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('firewall','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref30','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref30_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref31','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref31_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref32','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref32_live','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote30','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote31','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote32','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xforwarding','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xfast','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.5.4.1','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.1.5.4.2','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xtermFont','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('connect-localhost','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('refusedByServer','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('alternatives','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('RDP','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('vnc','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('vncx','section-4');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-4.2','section-4.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('emacsinx','section-4.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('emacsintelnet','section-4.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-5','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-5.1','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-5.1.1','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-5.1.2','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('mailcommand','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('mailsend','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-5.1.3.2','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref33','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref33_live','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote33','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('popmail','section-5');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-5.2','section-5.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('pinemain','section-5.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('pinecompose','section-5.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('pineindex','section-5.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-6','section-6');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xfermode','xfermode');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xfersamba','xfersamba');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref34','xfersamba');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref34_live','xfersamba');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote34','xfersamba');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('internetftp','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('anonprivateftp','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref35','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref35_live','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote35','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('ftpclient','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref36','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref36_live','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref37','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref37_live','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote36','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote37','internetftp');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xferproblems','xferproblems');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('dostounix','xferproblems');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('unixtodos','xferproblems');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.1','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('compshell','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref38','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref38_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('cStructure','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref39','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref39_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fig:compilation','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.1.1.1.1','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.1.1.1.2','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote39','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('compilingSingle','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('compilingMultiple','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('compilerOptions','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref40','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref40_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref41','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref41_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote40','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote41','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote38','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('errmsgs','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('capturing','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref42','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref42_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote42','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('understanding','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('javacomp','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref43','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref43_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('jproject','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote43','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.1.4','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('emacserr','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('emacs-next-error','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref44','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref44_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote44','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('vimcompile','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('vimscreen','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.2','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref45','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref45_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.2.1','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.2.2','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('artificial-targets','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('writingMakefiles','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.2.5','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote45','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.3','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.3.1','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref46','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref46_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref47','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref47_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote46','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote47','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.3.2','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.1.3.3','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('gdbmode','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref48','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref48_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref49','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref49_live','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote48','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote49','section-7');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.2','section-7.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.2.1','section-7.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-7.2.2','section-7.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('gdbxfig','section-7.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('dddfig','section-7.2');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-8','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('section-8.1','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref50','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref50_live','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('loginCustom','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref51','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref51_live','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref52','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fref52_live','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote51','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote52','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('xCustom','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('programCustom','section-8');
</script><script type="text/javascript">
checkForAnchorOnOtherPage('fn_fnote50','section-8');
</script><div class="sect2" id="section-8.2" ns0:xpath="//*[@id='section-8.2']" ns0:page="section-8.2" ns0:prev="/cocoon/~cs252/open/unix/section-8.html" ns0:up="/cocoon/~cs252/open/unix/section-8.html" ns0:first="/cocoon/~cs252/open/unix/unix.html"><div class="info_sect2"><div class="title_sect3">8.2. Scripting</div></div><div class="TOC">Contents:<div class="TOC-section2"><a href="#section-8.2.1">8.2.1 Parameters</a></div><div class="TOC-section2"><a href="#controlflow">8.2.2 Control Flow</a></div><div class="TOC-section2"><a href="#section-8.2.3">8.2.3 The <span class="code">test</span> and <span class="code">expr</span> Programs</a></div><div class="TOC-section2"><a href="#section-8.2.4">8.2.4 Scripting Example: The Student Test Manager</a></div><div class="TOC-section3"><a href="#section-8.2.4.1">8.2.4.1 Sample Scenario</a></div><div class="TOC-section3"><a href="#section-8.2.4.2">8.2.4.2 The Script</a></div><div class="TOC-section2"><a href="#scriptDebugging">8.2.5 Debugging Your Scripts</a></div><div class="TOC-section3"><a href="#section-8.2.5.1">8.2.5.1 Isolate the Problem</a></div><div class="TOC-section3"><a href="#section-8.2.5.2">8.2.5.2 Add Debugging Output</a></div><div class="TOC-section3"><a href="#tracing">8.2.5.3 Trace the Execution</a></div></div><p class="para">You can put any sequence of Unix commands into a file and turn that
file into a command. Such a file is called a <span class="emphasis">script</span>. For
example, suppose that you are working on a program <span class="code">myprog</span>
and have several files of test data that you run through it each time
you make a change.  Create a file <span class="code">dotest1</span> with the following
lines:
<div class="programlisting">
   ./myprog &lt; test1.dat &gt; test1.dat.out
   ./myprog &lt; test2.dat &gt; test2.dat.out
   ./myprog &lt; test3.dat &gt; test3.dat.out
   ./myprog &lt; test4.dat &gt; test4.dat.out
   ./myprog &lt; test5.dat &gt; test5.dat.out 
</div>
You can't execute <span class="code">dotest1</span> yet, because you don't have execute
permission. (Do <span class="code">ls -l dotest1</span> to see this.)  So use the
<span class="code">chmod</span> command to add execute permission:
<div class="screen"><span class="userinput">
chmod u+x dotest1
</span></div>
Now you can execute <span class="code">dotest1</span> by simply typing
<div class="screen"><span class="userinput">
./dotest1
</span></div></p><p class="para">Most shells provide special facilities for use in scripts. Since these
differ from one shell to another, it's a good idea to tell Unix which
shell to use when running the script. You do this by placing the
command <span class="code">#!/bin/csh</span> in the first line of the
script.</p><p class="para">In fact, you can list any program there, not just
<span class="code">/bin/csh</span>, and Unix will use that program to process the
remainder of the lines in the script.
<div class="itemizedlist"><ul><li>Any text file with execute permission can be invoked as a
program.</li><li>The first line must identify the program to be run (after a
starting <span class="code">#!</span>).</li><li>The remaining lines are fed to the standard input of that
program.</li></ul></div>
So another possibility for executing your test code would be to 
put the line <span class="code">#!./myprog</span> at the front of each of the test data
input files <span class="code">test1.dat</span>, <span class="code">test2.dat</span>, &#8230;, and then execute
those data files!</p><div class="sect3" id="section-8.2.1"><div class="info_sect3"><div class="title_sect4">8.2.1. Parameters</div></div>
    
    <p class="para">We can pass parameters to shell scripts from the command line.
For example, suppose we wanted a script to execute a single test like
this:
<div class="programlisting">
dotest2 test1.dat
</div>
that would feed <span class="code">test1.dat</span> (or whatever) to the input of
<span class="code">myprog</span>, saving the output in <span class="code">test1.dat.out</span>.</p>
    <p class="para">In <span class="code">csh</span>, we use  the symbol <span class="code">$k</span> to stand
for the <span class="inlineequation"><span class="mathphrase">k<sup>th</sup></span></span> argument given to the script. So we can write our
script <span class="code">dotest2</span>, as follows:
<div class="programlisting">
   #!/bin/csh
   ./myprog &lt; $1 &gt; $1.out
</div>
After the appropriate <span class="code">chmod</span>, this could then be invoked as 
<div class="screen"><span class="userinput">
   ./dotest2 test1.dat test2.dat test3.dat test4.dat test5.dat
</span></div></p>
    <p class="para">Of course, scripts can have more than one parameter. For example, try
saving this file as <span class="code">mcdonald</span>
<div class="programlisting">
#!/bin/sh
echo Old McDonald had a farm.
echo EIEIO
echo And on that farm he had a $1.
echo EIEIO
echo With a $2, $2 here,
echo And a $2, $2 there.
</div>
and then invoking it this way:
<div class="programlisting">
./mcdonald cow moo 
./mcdonald dog bark
</div></p>
  </div><div class="sect3" id="controlflow"><div class="info_sect3"><div class="title_sect4">8.2.2. Control Flow</div></div>
    
    <p class="para">Shells feature control flow based on <span class="quote">
      &#8220;status codes&#8221;
    </span> returned by
programs to indicate whether the program execution <span class="quote">
      &#8220;succeeded&#8221;
    </span> or <span class="quote">
      &#8220;failed&#8221;
    </span>. For example, this script tests to see if the <span class="code">gcc</span>
compiler has successfully compiled a file.</p>
    <p class="para">
      <table border="1">
        <tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML">
          <th>csh, tcsh</th>
          <th>sh, bash</th>
        </tr>
        <tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML">
          <td align="top">
            <div class="programlisting">
if ( { gcc -c expr.c } ) then
  echo All is well.
else
  echo Did not compile!
endif
</div>
          </td>
          <td align="top">
            <div class="programlisting">
if gcc -c expr.c;
then
  echo All is well.
else
  echo Did not compile!
fi
</div>
          </td>
        </tr>
      </table>	
    </p>
    <p class="para">In <span class="code">sh</span> (and its relatives <span class="code">bsh</span> and <span class="code">bash</span>), the <span class="code">if</span> is
followed by a list of commands, each terminated by a ';'. The status
code of the last command is used as the <span class="code">if</span> condition. In <span class="code">csh</span>
(and its relative, <span class="code">tcsh</span>), the condition must be placed inside
parentheses. To execute a command as part of the condition, place that
inside {} brackets (with white space to either side of each bracket).</p>
    <p class="para">This idea of returning a status code explains why, in C and C++, the
function <span class="code">main</span> is always supposed to return an <span class="code">int</span>. The
returned value is the status code. You are supposed to return a zero when your program works normally, but you are supposed to return a non-zero <span class="quote">
      &#8220;error code&#8221;
    </span> if your program terminates abnormally (e.g., if it discovers that a file it needs is missing).</p>

<p class="para">The shell <span class="code">if</span> statements will take the <span class="quote">
      &#8220;then&#8221;
    </span> branch when a command returns a status code of 0, but  any non-zero value denotes a failure and will cause the script to follow the <span class="quote">
      &#8220;else&#8221;
    </span> branch. Most Unix commands will list the status codes they return on their man pages<a onmouseover="DBshowBriefly('fn_fref53_live')" name="fn_fref53" id="fn_fref53" class="footnotemark" href="#fn_fnote53">53</a><div class="footnote_live" id="fn_fref53_live"><p class="para">The pages you get when running the command
<div class="programlisting">man <span class="emphasis-italic" role="italic">command</span></div>
</p></div>.
</p>

    <p class="para">Looping is also available in the shells. One of the most commonly used
loop forms is that of visiting every item in some list. The list is
often all files satisfying some wildcard pattern:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
foreach file (*.txt)
  echo $file
end
</div></td><td align="top"><div class="programlisting">
for file in *.txt
do
  echo $file
done
</div></td></tr></table></p>
    <p class="para">Another common kind of loop visits every parameter passed to the
script
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
foreach file ($*)
  echo $file
end
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
for x in $*
do
  echo $x
done
</div></td></tr></table>
<span class="code">$*</span> is a list of all the command parameters.
If either of these scripts were stored in a file <span class="code">testp</span> and then
invoked as
<div class="screen"><span class="userinput">
./testp a b c
</span></div>
the output would be
<div class="screen"><span class="computeroutput">
a
b
c
</span></div>
If invoked as 
<div class="screen"><span class="userinput">
./testp *.txt
</span></div>
the output would be a list of all <span class="code">.txt</span> files in the working
directory.</p>
    <p class="para">Another common scripting pattern is a script that has few special
parameters at the beginning, followed by an arbitrary number of
remaining parameters (often filenames). The <span class="code">shift</span> command helps
us to handle these. Each call to <span class="code">shift</span> removes he first element
of the <span class="code">$*</span> list.  These scripts, stored as <span class="code">testp2</span>:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set p1=$1
shift
set p2=$1
shift
echo The first two parameters are\
 $p1 and $p2
echo The remaining parameters are
foreach file ($*)
  echo $file
end
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
p1=$1
shift
p2=$1
shift
echo The first two parameters are\
 $p1 and $p2
echo The remaining parameters are
for x in $*
do
  echo $x
done
</div></td></tr></table>
and invoked as
<div class="screen"><span class="userinput">
./testp2 a b c d
</span></div>
would produce the output
<div class="screen"><span class="computeroutput">
echo The first two parameters are a and b
echo The remaining parameters are
c
d
</span></div></p>
    <p class="para">A while loop is also available.
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
while ( <span class="emphasis">condition</span> )
  <span class="emphasis">commands</span>
end
</div></td><td align="top"><div class="programlisting">
while <span class="emphasis">condition</span>;
do
  <span class="emphasis">commands</span>
done
</div></td></tr></table>
but it's kind of hard to see just what you could do with it given the
limited form of conditions we've looked at so far.</p>
  <div name="fn_fnote53" id="fn_fnote53" class="footnote">53. <p class="para">The pages you get when running the command
<div class="programlisting">man <span class="emphasis-italic" role="italic">command</span></div>
</p> (<a href="#fn_fref53">back</a>)
    </div></div><div class="sect3" id="section-8.2.3"><div class="info_sect3"><div class="title_sect4">8.2.3. The <span class="code">test</span> and <span class="code">expr</span> Programs</div></div>
    
    <p class="para">One thing that becomes obvious quickly is that the status code based
testing is limited. Often we want to
<div class="itemizedlist"><ul><li>Check for the presence/status of files</li><li>Do tests on strings, especially in variables &amp; script
parameters</li><li>Do numeric tests.</li></ul></div>
but status codes indicating whether or not a program executed
successfully don't seem to help us very much.</p>
    <p class="para">The solution is to use a program whose job is to 
<div class="itemizedlist"><ul><li>do the tests, and</li><li>return the appropriate value as a status code.</li></ul></div>
The Unix program that does this is called <span class="code">test</span>:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
gcc -c expr.c
if (-r expr.o) then
  echo All is well.
else
  echo Did not compile!
endif
</div></td><td align="top"><div class="programlisting">
gcc -c expr.c
if test -r expr.o;
then
  echo All is well.
else
  echo Did not compile!
fi
</div></td></tr></table>
The <span class="code">csh</span> shells automatically call <span class="code">test</span> in their <span class="code">if</span> and
<span class="code">while</span> loop conditions. The <span class="code">sh</span> family does not.</p>
    <p class="para"><span class="code">test</span> takes a bewildering variety of possible parameters. You can
see the whole list by giveng the command <span class="code">man test</span>.
Many of these are used for checking the status of various files. The
<span class="code">-r expr.o</span> in the above shells checks to see if a file named
<span class="code">expr.o</span> exists and if we have permission to read it.
Some common file tests are:
<p class="para" align="center"><table><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>test</th><th>is true if</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td>-r <span class="emphasis-italic" role="italic">file</span></td><td><span class="emphasis-italic" role="italic">file</span> exists and is readable</td></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td>-w <span class="emphasis-italic" role="italic">file</span></td><td><span class="emphasis-italic" role="italic">file</span> exists and is writable</td></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td>-x <span class="emphasis-italic" role="italic">file</span></td><td><span class="emphasis-italic" role="italic">file</span> exists and is executable</td></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td>-d <span class="emphasis-italic" role="italic">file</span></td><td><span class="emphasis-italic" role="italic">file</span> exists and is a directory</td></tr></table></p></p>
    <p class="para">Strings are compared with <span class="code">=~</span> and <span class="code">!~</span> in <span class="code">csh</span>, <span class="code">=</span> and
<span class="code">!=</span> in <span class="code">sh</span>. 
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
if ( $USER =~ zeil ) then
  echo Nice guy!
else
  echo Who are you?
endif
</div></td><td align="top"><div class="programlisting">
if test $USER = zeil;
then
  echo Nice guy!
else
  echo Who are you?
fi
</div></td></tr></table></p>
    <p class="para">Numbers are  compared with the conventional relational operators
(<span class="code">== != &lt; &gt; &lt;= &gt;=</span>) in <span class="code">csh</span>, but have more clumsy equivalents
in <span class="code">sh</span> (<span class="code">-eq -ne -lt -gt -le -ge</span>):
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
if ( $count == 0 ) then
  echo zero
else
  echo non-zero
endif
</div></td><td align="top"><div class="programlisting">
if test $count -eq 0;
then
  echo zero
else
  echo non-zero
fi
</div></td></tr></table></p>
    <p class="para">But where do numbers come from if all the variables contain strings?</p>
    <p class="para">From yet another program, of course. The shells themselves have no
built-in numeric capability. Calculations can be performed by the
<span class="code">expr</span> program. This program treats its arguments as an arithmetic
expression, evaluates that expression, and prints the result on
standard output. For example:
<div class="programlisting">
expr 1
<span class="code">1</span>
expr 2 + 3 \* 5
<span class="code">17</span>
</div>
Note the use of \ to <span class="quote">
      &#8220;quote&#8221;
    </span> the following character
(<span class="code">*</span>). Without that backwards slash, the shell into which we typed
the command would treat the <span class="code">*</span> as the filename wildcard, replacing
it with a list of all files in the current directory, and <span class="code">expr</span>
would have actually seen something along the lines of
<div class="programlisting">
expr 2 + 3 file1.txt file2.txt myfile.dat 5
</div></p>
    <p class="para">Now, how do we get the output of an <span class="code">expr</span> program evaluation into
a variable or a script expression where it can do some good? For this
we use the convention that the backwards apostrophes, <span class="code">`</span>, when
used to quote a string, mean <span class="quote">
      &#8220;execute this string as a shell command
and put its standard output right here in this command&#8221;
    </span>.</p>
    <p class="para">For example:
<div class="programlisting">
echo Snow White and the expr 6 + 1 Dwarves
<span class="code">Snow White and the expr 6 + 1 Dwarves</span>
echo Snow White and the `expr 6 + 1` Dwarves
<span class="code">Snow White and the 7 Dwarves</span>
</div></p>
    <p class="para">With these two ideas, we can now do numerical calculations in our
scripts:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
set count=0
foreach file (*)
  set count=`expr $count + 1`
end
echo There are $count files\
 in this directory.
</div></td><td align="top"><div class="programlisting">
count=0
for file in *
do
  count=`expr $count + 1`
done
echo There are $count files\
 in this directory.
</div></td></tr></table></p>
  </div><div class="sect3" id="section-8.2.4"><div class="info_sect3"><div class="title_sect4">8.2.4. Scripting Example: The Student Test Manager</div></div><div class="TOC">Contents:<div class="TOC-section3"><a href="#section-8.2.4.1">8.2.4.1 Sample Scenario</a></div><div class="TOC-section3"><a href="#section-8.2.4.2">8.2.4.2 The Script</a></div></div>
    
    <p class="para">As an example of how to bring all those scripting details together,
let's look at some scripts to aid in testing programs. Many
programming students wind up adopting a hit-and-miss approach to
testing their code, in part because they don't set themselves up with
an easy way to repeat a large number of tests every time they make a
change to their programs.</p>
    <p class="para">What we'd like to end up with is a simple system for testing non-GUI
programs. The idea is that the student designs a number of tests and
can then issue a command to run all or a selected subset of those
tests. The command should run those tests, capturing the program
outputs in files that the student can examine later. Furthermore, we
can save the student a bit of time by letting him or her know if the
program output has changed on any of those tests.</p>
    <div class="sect4" id="section-8.2.4.1"><div class="info_sect4"><div class="title_sect5">8.2.4.1. Sample Scenario</div></div>
      
      <p class="para">So, suppose the student is working on a program named <span class="code">myProg</span> and
has designed 20 test cases. Once the program compiles successfully,
the student could say
<div class="screen"><span class="userinput">
./runTests ./myProg 1 20
</span></div>
to run all 20 tests. The output might look something like:
<div class="screen"><span class="computeroutput">
Starting test 1...
Starting test 2...
Starting test 3...
Starting test 4...
</span></div>
Maybe at this point the output stops, suggesting that the program has
been caught in an infinite loop. The student kills the program with^-C. Now looking in the directory, the student finds files
<span class="code">testOut1.txt</span>, <span class="code">testOut2.txt</span>, <span class="code">testOut3.txt</span>, and
<span class="code">testOut4.txt</span> corresponding to the tests thatwere actually
started. The student looks at the first 3 of these, decides that the
captured output looks correct, and starts debugging the program to
figure out why it hung up on test 4. Eventually the student makes
change to the program, recompiles it, and tries again, this time just
running test 4.
<div class="screen"><span class="userinput">
./runTests ./myProg 4 4
Starting test 4...
** Test 4 output has changed
</span></div>
Not surprisingly, the output from test 4 is different, because the
infinite loop has now, apparently been fixed. Checking
<span class="code">testOut4.txt</span>, everything looks good.</p>
      <p class="para">Encouraged, the student launches the whole test set once again
<div class="screen"><span class="userinput">
./runTests ./myProg 1 20
Starting test 1...
Starting test 2...
** Test 2 output has changed
Starting test 3...
** Test 3 output has changed
Starting test 4...
Starting test 5...
  <span class="inlineequation"><span class="mathphrase"><m:math xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xi="http://www.w3.org/2001/XInclude"><m:mo>&#8942;</m:mo></m:math></span></span>
Starting test 20...
</span></div>
The unexpected has occurred. The fix to make test 4 work has changed
the behavior of the program on tests 2 and 3, which had previously
been believed to be OK. The student must go back and check these (as
well as the outputs of tests 5&#8230;20) to see what has
happened. Annoying? Yes, but it's better that the student should discover
these changes in behavior before submitting than that the grader
should do so after submission!</p>
    </div>
    <div class="sect4" id="section-8.2.4.2"><div class="info_sect4"><div class="title_sect5">8.2.4.2. The Script</div></div>
      
      <p class="para">As we have envisioned it, our <span class="code">runTests</span> script takes three
parameters:
<div class="orderedlist"><ol><li>The name of the program to run</li><li>The number of the first test to be performed</li><li>The number of the last test to be performed</li></ol></div></p>
      <p class="para">So we start our script by gathering those three parameters:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set programName=$1
set firstTest=$2
set lastTest=$3
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
programName=$1
firstTest=$2
lastTest=$3
</div></td></tr></table></p>
      <p class="para">Clearly, the main control flow here will be a loop going through the
requested test numbers.
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set programName=$1
set firstTest=$2
set lastTest=$3
#
# Loop through all tests
set testNum=$firstTest
while ($testNum &lt;= $lastTest)
   <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
  set testNum=`expr $testNum + 1`
end
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
programName=$1
firstTest=$2
lastTest=$3
#
# Loop through all tests
testNum=$firstTest
while test $testNum -le $lastTest;
do
   <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
  testNum=`expr $testNum + 1`
done
</div></td></tr></table></p>
      <p class="para">For each test, we will eventually want to compare the output from this
test, stored in <span class="code">testOut<span class="inlineequation"><span class="mathphrase">i</span></span>.txt</span> to the output from the previous
test, which we will assume is stored in <span class="code">testOut<span class="inlineequation"><span class="mathphrase">i</span></span>.old.txt</span>. The
<span class="code">cmp</span> command lets us compare two files to see if their contents
are identical.
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set programName=$1
set firstTest=$2
set lastTest=$3
#
# Loop through all tests
set testNum=$firstTest
while ($testNum &lt;= $lastTest)
   <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
<span class="emphasis-highlight1" role="highlight1"># Has the output changed?
  if (-r testOut$testNum.old.txt) then
    if ( ! { cmp testOut$testNum.old.txt testOut$testNum.txt } ) then
       echo \*\* Test $testNum output has changed
    endif
  endif</span>
  set testNum=`expr $testNum + 1`
end
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
programName=$1
firstTest=$2
lastTest=$3
#
# Loop through all tests
testNum=$firstTest
while test $testNum -le $lastTest;
do
   <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
<span class="emphasis-highlight1" role="highlight1"># Has the output changed?
  if test -r testOut$testNum.old.txt;
  then
    if cmp testOut$testNum.old.txt testOut$testNum.txt;
    then
       donothing=0
    else
       echo \*\* Test $testNum output has changed
    fi
  fi</span>
  testNum=`expr $testNum + 1`
done
</div></td></tr></table></p>
      <p class="para">To set this up, we must determine just where the <span class="code">.old.txt</span> files
come from. They are simply the previous version of the test output
files (if that particular test has ever been run).
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set programName=$1
set firstTest=$2
set lastTest=$3
#
# Loop through all tests
set testNum=$firstTest
while ($testNum &lt;= $lastTest)
<span class="emphasis-highlight1" role="highlight1"># Save the previous output from this test
  if (-r testOut$testNum.txt) then
    /bin/mv testOut$testNum.txt testOut$testNum.old.txt
  endif</span>
   <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
#
# Has the output changed?
  if (-r testOut$testNum.old.txt) then
    if ( ! { cmp testOut$testNum.old.txt testOut$testNum.txt } ) then
       echo \*\* Test $testNum output has changed
    endif
  endif
  set testNum=`expr $testNum + 1`
end
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
programName=$1
firstTest=$2
lastTest=$3
#
# Loop through all tests
testNum=$firstTest
while test $testNum -le $lastTest;
do
<span class="emphasis-highlight1" role="highlight1"># Save the previous output from this test
  if test -r testOut$testNum.txt;
  then
    /bin/mv testOut$testNum.txt testOut$testNum.old.txt
  fi</span>
   <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
#
# Has the output changed?
  if test -r testOut$testNum.old.txt;
  then
    if cmp testOut$testNum.old.txt testOut$testNum.txt;
    then
       donothing=0
    else
       echo \*\* Test $testNum output has changed
    fi
  fi
  testNum=`expr $testNum + 1`
done
</div></td></tr></table></p>
      <p class="para">Finally, we come to the heart of the matter. We need to actually
execute the program, saving the output in the appropriate
<span class="code">testOut&#8230;</span> file. Exactly how we want to execute the program
depends upon how the program gets its input data. I'm going to assume,
for the moment, that this program reads its input data from the
standard input stream, and that the student saves the input test cases
in <span class="code">testIn1.txt</span>, <span class="code">testIn2.txt</span>, &#8230;.
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set programName=$1
set firstTest=$2
set lastTest=$3
#
# Loop through all tests
set testNum=$firstTest
while ($testNum &lt;= $lastTest)
#
# Save the previous output from this test
  if (-r testOut$testNum.txt) then
    /bin/mv testOut$testNum.txt testOut$testNum.old.txt
  endif
<span class="emphasis-highlight1" role="highlight1"># Run the test!
  echo Starting test $testNum...
  $programName &lt; testIn$testNum.txt &gt;&amp; testOut$testNum.txt</span>
#
# Has the output changed?
  if (-r testOut$testNum.old.txt) then
    if ( ! { cmp testOut$testNum.old.txt testOut$testNum.txt } ) then
       echo \*\* Test $testNum output has changed
    endif
  endif
  set testNum=`expr $testNum + 1`
end
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
programName=$1
firstTest=$2
lastTest=$3
#
# Loop through all tests
testNum=$firstTest
while test $testNum -le $lastTest;
do
#
# Save the previous output from this test
  if test -r testOut$testNum.txt;
  then
    /bin/mv testOut$testNum.txt testOut$testNum.old.txt
  fi
<span class="emphasis-highlight1" role="highlight1"># Run the test!   
  echo Starting test $testNum...
  $programName &lt; testIn$testNum.txt 2&gt;&amp;1 &gt; testOut$testNum.txt</span>
#
# Has the output changed?
  if test -r testOut$testNum.old.txt;
  then
    if cmp testOut$testNum.old.txt testOut$testNum.txt;
    then
       donothing=0
    else
       echo \*\* Test $testNum output has changed
    fi
  fi
  testNum=`expr $testNum + 1`
done
</div></td></tr></table></p>
      <p class="para">By making minor changes to the way the program is run, we can
accommodate a number of different possible program styles.
How would you change these scripts for a program that read no inputs
at all, but could be invoked with different command-line parameters?</p>
      <p class="para">There are a number of possibilities, but I would put the various
parameters into the <span class="code">testIn&#8230;</span> files, and run them this way:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
    <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
#
# Run the test!   
  echo Starting test $testNum...
  $programName `sed -e s/[\\r\\n]//g testIn$testNum.txt` \
   &gt;&amp;  testOut$testNum.txt
    <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
    <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
#
# Run the test!   
  echo Starting test $testNum...
  $programName `sed -e s/[\\r\\n]//g testIn$testNum.txt` \
   2&gt;&amp;1 &gt; testOut$testNum.txt
    <span class="inlineequation"><span class="mathphrase"><m:math><m:mo>&#8942;</m:mo></m:math></span></span>
</div></td></tr></table></p>
    </div>
  </div><div class="sect3" id="scriptDebugging"><div class="info_sect3"><div class="title_sect4">8.2.5. Debugging Your Scripts</div></div><div class="TOC">Contents:<div class="TOC-section3"><a href="#section-8.2.5.1">8.2.5.1 Isolate the Problem</a></div><div class="TOC-section3"><a href="#section-8.2.5.2">8.2.5.2 Add Debugging Output</a></div><div class="TOC-section3"><a href="#tracing">8.2.5.3 Trace the Execution</a></div></div>
    
    <p class="para">Scripting is just another form of programming. Just like programs that you write in C++ or other <span class="quote">
      &#8220;traditional&#8221;
    </span> programming languages, you need to test your scripts to see if they work,  and, just like those other programs, your scripts are probably not going  to work correctly on the first try.</p>
    <p class="para">Debugging your scripts is not all that different from debugging
traditional programs, either. Many of the basic techniques are
similar:</p>
    <div class="sect4" id="section-8.2.5.1"><div class="info_sect4"><div class="title_sect5">8.2.5.1. Isolate the Problem</div></div>
      
      <p class="para"> If you have a script that does
several things in succession, try to determine how far along that
sequence you have been getting before things go wrong. The whole
reasoning process that we call <span class="quote">
      &#8220;debugging&#8221;
    </span> is a lot easier if you
know where to look.</p>
      <p class="para">You can try to do this by examining any intermediate results to see if
they are correct. In particular, if your script produces some
temporary or working files, look at those. If your script <span class="code">rm</span>s
those files when it's done with them, try commenting out the <span class="code">rm</span>
statements (put a # in front of them) until you're sure everything is
working. Another way to examine intermediate results is by adding
debugging output to print them out (see below).</p>
      <p class="para">If that doesn't work, you can try <span class="quote">
      &#8220;shortening&#8221;
    </span> your script by
commenting out the later steps and seeing if the partial script seems
to work, then uncommenting the next step and testing the script again,
and so on.</p>
    </div>


    <div class="sect4" id="section-8.2.5.2"><div class="info_sect4"><div class="title_sect5">8.2.5.2. Add Debugging Output</div></div>
      
      <p class="para"> Just as you might add extra
output statements to a C++ program to reveal the values of selected
importatnt variables, you can do the same thing with scripts. The
<span class="code">echo</span> command is used for this purpose. For example, if we were
having problems with this script:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set count=0
foreach file (*)
  set count=`expr $count + 1`
end
echo There are $count files\
 in this directory.
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
count=0
for file in *
do
  count=`expr $count + 1`
done
echo There are $count files\
 in this directory.
</div></td></tr></table>
we might add some temporary output to see just what was going on inside
the loop:
<table border="1"><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><th>csh, tcsh</th><th>sh, bash</th></tr><tr xmlns:xi="http://www.w3.org/2001/XInclude" xmlns:m="http://www.w3.org/1998/Math/MathML"><td align="top"><div class="programlisting">
#!/bin/csh
set count=0
foreach file (*)
<span class="emphasis-highlight1" role="highlight1">  echo Looking at $file.</span>
  set count=`expr $count + 1`
<span class="emphasis-highlight1" role="highlight1">  echo Count is $count.</span>
end
echo There are $count files\
 in this directory.
</div></td><td align="top"><div class="programlisting">
#!/bin/sh
count=0
for file in *
do
<span class="emphasis-highlight1" role="highlight1">  echo Looking at $file.</span>
  count=`expr $count + 1`
<span class="emphasis-highlight1" role="highlight1">  echo Count is $count.</span>
done
echo There are $count files\
 in this directory.
</div></td></tr></table>
Debugging output like this not only reveals the values of variables,
but also can be valuable in showing which branch of an <span class="code">if</span> was
selected, how many times a loop is executed, etc.</p>



<p class="para">
Because <span class="code">echo</span> can print pretty much anything you give it as an argument, it's particularly useful when you have a script that runs other programs and suspect that your script may not be invoking those programs correctly. For example, if you have a script <span class="code">huntFor</span>:
<div class="programlisting">
#!/bin/sh
#
# Hunt through a list of files for
# a string. E.g.,
#   huntFor sqrt *.cpp
#   
Search=$1
shift
grep -l $Search $* 
</div>
and are wondering if the grep command is being issued the way you expect,
you might try:
<div class="programlisting">
#!/bin/sh
#
# Hunt through a list of files for
# a string. E.g.,
#   huntFor sqrt *.cpp
#   
Search=$1
shift
<span class="emphasis-highlight1" role="highlight1">echo grep -l $Search $* </span>
grep -l $Search $* 
</div>
to see the command just before it gets issued.  
</p>

<p class="para">You might find it valuable to actually create the above script, storing it in a file named <span class="code">huntFor</span>, and try testing it like this:
<div class="programlisting">
./huntFor yes ~/UnixCourse/compileAsst/*.cpp
./huntFor bigger ~/UnixCourse/compileAsst/*.cpp
./huntFor "bigger than" ~/UnixCourse/compileAsst/*.cpp
</div>
The last case reveals a problem, which is easily fixed:
<div class="programlisting">
#!/bin/sh
#
# Hunt through a list of files for
# a string. E.g.,
#   huntFor sqrt *.cpp
#   
Search=$1
shift
grep -l <span class="emphasis-highlight1" role="highlight1">"</span>$Search<span class="emphasis-highlight1" role="highlight1">"</span> $* 
</div>
If you have tried those tests and don't see how this fix works, review <a url="../typing/quoting.html#quoting" href="../typing/quoting.html#quoting">Quoting</a>.
</p>

<p class="para">The use of <span class="code">echo</span> to print out entire commands does carry a bit of a risk if the commands involve <a url="../redirection/" href="../redirection/">output redirection or pipes</a>. For example, if the original command is redirecting its output into a file:
<div class="programlisting">
cat $1 $2 &gt; $3
</div>
then throwing an <span class="code">echo</span> version in front:
<div class="programlisting">
echo cat $1 $2 &gt; $3
cat $1 $2 &gt; $3
</div>
will actually result in your debugging output being written into the output file, probably messing things up even more than they were before.
</p>

<p class="para">In cases like that, you can obtain the same information more easily by our next technique, <a url="#tracing" href="#tracing">tracing the execution</a>.
</p>
    </div>





    <div class="sect4" id="tracing"><div class="info_sect4"><div class="title_sect5">8.2.5.3. Trace the Execution</div></div>
      
      <p class="para">
If you were working with a C++ program, you could use <span class="code">gdb</span> or
<span class="code">ddd</span> to step through the program and see exactly which statements
were being executed, in which order.</p>
      <p class="para">Shells provide a more primitive, but still useful, tracing
facility. The <span class="quote">
      &#8220;<span class="code">-x</span>&#8221;
    </span> option, supplied to <span class="code">sh</span> or <span class="code">csh</span>,
asks it to list each command before it executes it (and after
replacing any variables by their values).</p>
      <p class="para">So, if you have written a shell script named <span class="quote">
      &#8220;<span class="code">myScript</span>&#8221;
    </span> with
the first line: 
<div class="programlisting">
#!/bin/sh
</div>
you might test it this way:
<div class="programlisting">
sh -x myScript <span class="emphasis">parameters</span>
</div>
or if it began with the line
<div class="programlisting">
#!/bin/csh
</div>
you might test it this way:
<div class="programlisting">
csh -x myScript <span class="emphasis">parameters</span>
</div></p>
    </div>
  </div></div><br/><table width="100%" class="navigationBar"><tr class="navigationBar"><td width="5%" class="navigationBar"><a class="navigationBarArrow" title="First" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/unix.html"><img class="navigationBar" src="_axle/first.gif" alt="First"/></a></td><td width="5%" class="navigationBar"><a class="navigationBarArrow" title="Prev" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/section-8.html"><img class="navigationBar" src="_axle/prev.gif" alt="Prev"/></a></td><td width="5%" class="navigationBar"><a class="navigationBarArrow" title="Up" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/open/unix/section-8.html"><img class="navigationBar" src="_axle/up.gif" alt="Up"/></a></td><td class="navigationBar"/><td width="5%" class="navigationBar"><a class="navigationBar" title="CS252 Home" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/directory/announcements.html"><img class="navigationBar" src="_axle/home.gif" alt="CS252 Home"/></a></td><td width="5%" class="navigationBar"><a class="navigationBar" title="discuss this page" href="http://cocoon.cs.odu.edu:80/cocoon/~cs252/forum/getXPath/open/unix/section-8.2.html"><img class="navigationBar" src="_axle/forum.gif" alt="discuss this page"/></a></td></tr></table></body></html>