{"id":3272,"date":"2014-06-28T23:06:07","date_gmt":"2014-06-28T15:06:07","guid":{"rendered":"http:\/\/rmohan.com\/?p=3272"},"modified":"2014-06-28T23:06:07","modified_gmt":"2014-06-28T15:06:07","slug":"unix-shell-scripting","status":"publish","type":"post","link":"https:\/\/mohan.sg\/?p=3272","title":{"rendered":"UNIX Shell Scripting"},"content":{"rendered":"<p>UNIX Shell Scripting<\/p>\n<p>The basic concept of a shell script is a list of commands, which are listed in the order of execution. A good shell script will have comments, preceded by a pound sign, #, describing the steps. There are conditional tests, such as value A is greater than value B, loops allowing us to go through massive amounts of data, files to read and store data, and variables to read and store data, and the script may include functions.<br \/>\nShell scripts and functions are both interpreted. This means they are not compiled. Both shell scripts and functions are ASCII text that is read by the Korn shell command interpreter. When we execute a shell script, or function, a command interpreter goes through the ASCII text line by line, loop by loop, test by test and executes each statement, as each line is reached from the top to the bottom.<\/p>\n<p>1.      A shell is an environment in which we can run our commands, programs, and shell scripts. There are different flavors of shells, just as there are different flavors of operating systems. Each flavor of shell has its own set of recognized commands and functions.<\/p>\n<p>                     Korn Shell \/bin\/ksh OR \/usr\/bin\/ksh<\/p>\n<p>The standard Shell on Linux is the Bourne Again shell (bash) shell, and some others use Bourne shell (sh) as the default. To find your Default shell:<br \/>\n                              Echo $SHELL<br \/>\n2.      If the special characters are used to in a way that their special meaning is not needed then they must be escaped. To escape or remove its special function, the character must be preceded with a backslash \\ or enclosed within \u201c\u201cforward tic mark.<\/p>\n<p>                      \\  (  ;  #  $  ?  &#038;  *  ( )  [ ]  `  \u2018  \u201c  +<br \/>\n3.      A shell script can be executed in the following ways:<\/p>\n<p>                   Ksh shell_script_name<\/p>\n<p>a.      Will create a Korn shell and execute the shell_script_name in the newly created Korn shell environment.<br \/>\n                 shell_script_name<br \/>\nThe script will execute in the shell that is declared on the first line of the shell script. If no shell is declared on the first line of the shell script, it will execute in the default shell, which is the user\u2019s system-defined shell. Executing in an unintended shell may result in a failure and give unpredictable results.<\/p>\n<p>Declare the Shell in the Shell Script:<\/p>\n<p>We MUST declare the shell in the very first line of the script. If no shell is declared, the script will execute in the default shell, defined by the system for the user executing the shell script.<\/p>\n<p>#! \/usr\/bin\/ksh OR #! \/bin\/ksh.<br \/>\n#! \/usr\/bin\/sh OR #! \/bin\/sh               declares a Bourne shell<br \/>\n#! \/usr\/bin\/ksh OR #! \/bin\/ksh            declares a Korn shell<br \/>\n#! \/usr\/bin\/csh OR #! \/bin\/csh            declares a C shell<br \/>\n#! \/usr\/bin\/bash OR #! \/bin\/bash       declares a Bourne-Again shell<br \/>\nComments:<\/p>\n<p>We have to write code that is readable and has an easy flow. This involves writing a script that is easy to read and easily maintained, which means that it must have plenty of comments describing the steps.<br \/>\n#!\/usr\/bin\/ksh<br \/>\n#<br \/>\n# SCRIPT          : NAME_of_SCRIPT<br \/>\n# AUTHOR       : AUTHORS_NAME<br \/>\n# DATE                        : DATE_of_CREATION<br \/>\n# REV               : 1.1.A (Valid are A, B, D, T and P)<br \/>\n                           (For Alpha, Beta, Dev, Test and Production)<br \/>\n## PLATFORM : (SPECIFY: AIX, HP-UX, Linux, Solaris or Not platform dependent)<br \/>\n#<br \/>\n# PURPOSE      :  Give a clear, and if necessary, long, description of the purpose<br \/>\n                              Of  the shell script.<\/p>\n<p>#<br \/>\n# REV LIST:<br \/>\n#          DATE                           : DATE_of_REVISION<br \/>\n#          BY                                : AUTHOR_of_MODIFICATION<br \/>\n#          MODIFICATION           : Describe what was modified, new feature, etc.<br \/>\n#<br \/>\n# set -n          # Uncomment to check your syntax, without execution.<br \/>\n#                     # NOTE: Do not forget to put the comment back in or<br \/>\n#                    # the shell script will not execute!<br \/>\n# set -x         # Uncomment to debug this shell script (Korn shell only)<br \/>\n##########################################################<\/p>\n<p>########### DEFINE FILES AND VARIABLES HERE ##############<br \/>\n##########################################################<\/p>\n<p>############### DEFINE FUNCTIONS HERE ####################<br \/>\n##########################################################<\/p>\n<p>##########################################################<br \/>\n################ BEGINNING OF MAIN #######################<br \/>\n##########################################################<\/p>\n<p># End of script<br \/>\nFunctions:<br \/>\nwe can write a piece of code, which is used over and over, just once and use it without having to rewrite the code every time. We just call the function instead.<\/p>\n<p>Form of the function<\/p>\n<p>Function function_name<br \/>\n{<br \/>\nCommands to execute<br \/>\n}<br \/>\nOr<br \/>\nfunction_name ()<br \/>\n{<br \/>\nCommands to execute<br \/>\n}<br \/>\nControl Structures:<\/p>\n<p>If &#8230; then Statement<\/p>\n<p>If       [test_command]<br \/>\nThen<br \/>\n          Commands<br \/>\nFi<br \/>\nIf &#8230; then &#8230; else Statement<br \/>\nIf [test_command]<br \/>\nThen<br \/>\n          Commands<br \/>\nElse<br \/>\n           Commands<br \/>\nFi<br \/>\nIf &#8230; then &#8230; elif &#8230; (else) Statement<br \/>\nIf         [test_command]<br \/>\nThen<br \/>\n          Commands<br \/>\nElif         [test_command]<br \/>\nThen<br \/>\n        Commands<br \/>\nElse (Optional)<br \/>\n           Commands<br \/>\nFi<br \/>\nFor &#8230; in Statement<br \/>\nFor        loop_variable in argument list<br \/>\nDo<br \/>\nCommands<br \/>\nDone<\/p>\n<p>While Statement<br \/>\nWhile     test_command_is_true<br \/>\ndo<br \/>\n        Commands<br \/>\nDone<br \/>\nUntil Statement<br \/>\nuntil     test_command_is_true<br \/>\ndo<br \/>\n        Commands<br \/>\nDone<br \/>\nCase Statement<br \/>\ncase    $variable in<br \/>\nmatch_1)<br \/>\ncommands_to_execute_for_1<br \/>\n;;<br \/>\nmatch_2)<br \/>\ncommands_to_execute_for_2<br \/>\n;;<br \/>\nmatch_3)<br \/>\ncommands_to_execute_for_3<br \/>\n;;<br \/>\n.<br \/>\n.<br \/>\n.<br \/>\n*)      (Optional &#8211; any other value)<br \/>\ncommands_to_execute_for_no_match<br \/>\n;;<br \/>\nesac<\/p>\n<p>Break Continue, exit and return:<\/p>\n<p>It is sometimes necessary to break out of a for  or while loop, continue in the next block of code, exit completely out of the script, or return a function\u2019s result back to the script that called the function.<br \/>\nBreak: Is used to terminate the execution of the entire loop, after completing the execution of all of the lines of code up to the break statement. It then steps down to the code following the end of the loop.<br \/>\nContinue: Is used to transfer control to the next set of code, but it continues execution of the loop.<br \/>\nExit: Will do just what one would expect: It exits the entire script. An integer may be added to an exit command (for example, exit 0), which will be sent as the return code.<br \/>\nReturn: Is used in a function to send data back, or return a result, to the calling script.<\/p>\n<p>Here Document:<br \/>\nA here document is used to redirect input into an interactive shell script or program. The input that is supplied must be the exact data that the program is expecting, and many programs will fail if spaces are added to the input.<br \/>\nSyntax for a Here Document<br \/>\nprogram_name <<LABEL\nProgram_Input_1\nProgram_Input_2\nProgram_Input_3\nProgram_Input_#\nLABEL\nEXAMPLE:\n\/usr\/local\/bin\/My_program << EOF\nRandy\nRobin\nRusty\nJim\nEOF\n\nMost useful UNIX commands in Shell Scripting\nPasswd        : Change user password\nPwd      : print working Directory\nCd                 :  Change directory\nLs           : list of files in a directory\nWildcards   : * matches any number of    \n                       characters, \u2018?\u2019 matches a single  \n                        character\nFile        : print the type of file\nCat                : Displays the content of the file\nPr          : Displays the contents of a file\npg or page   : Display the contents of a file one  \n                       page at a time\nMore    : Display the contents of a file one  \n                        page at a time\nClear             : Clears the screen\nCp or\nCopy     : copy a file\nChown          : Change the owner of a file\nchgrp    : Change the group of a file\nchmod          : Change file modes, permissions\nrm         : Remove a file from the system\nmv                 : Rename a file\nmkdir   : Create a directory\nrmdir            : Remove a directory\ngrep      : Pattern matching\nEgrep             : grep command for extended  \n                        regular expressions\nfind       : Used to locate files and directories\n>>                  : Append to the end of a file<br \/>\n>            : Redirect, create, or overwrite a<br \/>\n                         file<br \/>\n|                    : Pipe, used to string commands<br \/>\n                         together<\/p>\n<p>||         : Logical OR\u2014command1 ||command2<br \/>\n               \u2014execute command2 if command1<br \/>\n               fails<br \/>\n&#038;                : Execute in background<\/p>\n<p>&#038;&#038;       : Logical AND\u2014command1 &#038;&#038;<br \/>\n               command2\u2014execute  command2 if<br \/>\n               command1 succeeds<br \/>\ndate         : Display the system date and time<br \/>\necho    : Write strings to standard output<br \/>\nsleep   : Execution halts for the specified<br \/>\n                number of seconds<br \/>\nwc       : Count the number of words, lines,<br \/>\n                and characters in a file<br \/>\nhead    : View the top of a file<br \/>\ntail       : View the end of a file<br \/>\ndiff      : Compare two files<\/p>\n<p>sdiff     : Compare two files side by side<br \/>\n                (requires 132-character display)<br \/>\nspell    : Spell checker<br \/>\nlp, lpr,<br \/>\nenq, qprt : Print a file<br \/>\nlpstat :Status of system print queues<br \/>\nenable  : Enable, or start, a print queue<br \/>\ndisable : Disable, or stop, a print queue<br \/>\nrwall    : Display a message to all users on a<br \/>\n                remote host<br \/>\nrsh or remsh<br \/>\n            : Execute a command, or log in, on a<br \/>\n                remote host<br \/>\ndf         : File systems statistics<\/p>\n<p>ps        : Information on currently running<br \/>\n               processes<br \/>\nnetstat  : Show network status<\/p>\n<p>vmstat   :Show virtual memory status<br \/>\ncal       : Display a calendar<br \/>\nwho     : Display information about users on<br \/>\n                the system<br \/>\nw         : Extended who command<br \/>\nwhoami : Display $LOGNAME or $USER<br \/>\n                 environment parameter<\/p>\n<p>who am I : Display login name, terminal, login<br \/>\n                    date\/time, and where logged in<\/p>\n<p>f, finger : Information about logged-in users<br \/>\n                 including the users .plan and .project<br \/>\ntalk      : Two users have a split screen<br \/>\n                conversation<br \/>\nwrite   : Display a message on a user\u2019s screen<\/p>\n<p>wall     : Display a message on all logged-in<br \/>\n               users\u2019 screens<br \/>\niostat : Show input\/output status<br \/>\nuname : Name of the current operating<br \/>\n                system, as well as machine<br \/>\n               information<br \/>\nsar       : System activity report<\/p>\n<p>basename : Base filename of a string<br \/>\n                       parameter<br \/>\nman     : Display the on-line reference manual<\/p>\n<p>su        : Switch to another user, also known as<br \/>\n                super-user<br \/>\ncut       : Write out selected characters<\/p>\n<p>awk     : Programming language to parse<br \/>\n                characters<br \/>\nsed      : Programming language for character<br \/>\n                substitution<br \/>\nvi         : Start the vi editor<br \/>\nemacs : Start the emacs editor<br \/>\n`command` :  Command substitution<br \/>\n( )          : Run the enclosed command in a sub-<br \/>\n                  shell<br \/>\n(( ))       : Evaluate and assign value to variable<br \/>\n                and do math in a shell<br \/>\n$(( ))     : Evaluate the enclosed expression<br \/>\n[ ]          : Same as the test command<br \/>\n[[ ]]       : Used for string comparison<br \/>\n$( )        : Command substitution<\/p>\n<p>Variables:<br \/>\nA variable is a character string to which we assign a value. The value assigned could be a number, text, filename, device, or any other type of data. A variable is nothing more than a pointer to the actual data.<\/p>\n<p>To assign a variable to point to data:<br \/>\n$VARIABLE_NAME=\u201dvalue_to_assign\u201d<br \/>\nTo view the data assigned to the variable<br \/>\n           Echo $UPPERCASE or print $UPPERCASE for variables<br \/>\n         Cat $UPPERCASE if the variable pointing to a file, as a command structure<br \/>\nCommand-Line Arguments:<br \/>\nThe command-line arguments $1, $2, $3,&#8230;$9 are positional parameters, with $0 pointing to the actual command, program, shell script, or function and $1, $2, $3, &#8230;$9 as the arguments to the command.<\/p>\n<p>Note: The positional parameters, $0, $2, etc., in a function, are for the function\u2019s use and may not be in the environment of the shell script that is calling the function. Where a variable is known in a function or shell script is called the scope of the variable.<\/p>\n<p>Shift Command<br \/>\nThe shift command is used to move positional parameters to the left; for example, shift causes $2 to become $1. We can also add a number to the shift command to move the positions more than one position; for example, shift 3 causes $4 to move to the $1 position.<\/p>\n<p>Special Parameters $* and $@<br \/>\nThe $* special parameter specifies all command-line arguments.<br \/>\nThe $@ special parameter also specifies all command-line arguments.<br \/>\nThe \u201c$*\u201d special parameter takes the entire list as one argument with spaces between.<br \/>\nThe \u201c$@\u201d special parameter takes the entire list and separates it into separate arguments.<\/p>\n<p>Double Quotes \u201c, Forward Tics \u2019, and Back Tics `<br \/>\nWe use \u201c, double quotes, in a statement where we want to allow character or command substitution.<br \/>\nWe use \u2018, forward tics, in a statement where we do not want character or command substitution.<br \/>\nWe use `, back tics, in a statement where we want to execute a command, or script, and have its output substituted instead; this is command substitution.<br \/>\nMath in a Shell Script<br \/>\nThe Korn shell let command and the ((expr)) command expressions are the most commonly used methods to evaluate an integer expression.<\/p>\n<p>Operators<br \/>\n++ \u2014<br \/>\nAuto-increment and auto-decrement, both prefix and postfix<br \/>\n+<br \/>\nUnary plus<br \/>\n&#8211;<br \/>\nUnary minus<br \/>\n!~<br \/>\nLogical negation; binary inversion (one\u2019s complement)<br \/>\n* \/ %<br \/>\nMultiplication; division; modulus (remainder)<br \/>\n+ &#8211;<br \/>\nAddition; subtraction<br \/>\n<< >><br \/>\nBitwise left shift; bitwise right shift<br \/>\n<= >=<br \/>\nLess than or equal to; greater than or equal to<br \/>\n< ><br \/>\nLess than; greater than<br \/>\n== !=<br \/>\nEquality; inequality (both evaluated left to right)<br \/>\n&#038;<br \/>\nBitwise AND<br \/>\n^<br \/>\nBitwise exclusive OR<br \/>\n|<br \/>\nBitwise OR<br \/>\n&#038;&#038;<br \/>\nLogical AND<br \/>\n||<br \/>\nLogical OR<\/p>\n<p>Chmod Permissions<\/p>\n<p>4000<br \/>\nSets user ID on execution<br \/>\n2000<br \/>\nSets group ID on execution<br \/>\n1000<br \/>\nSets the link permission to directories or sets the save-text attribute for files.<br \/>\n0400<br \/>\nPermits read by owner<br \/>\n0200<br \/>\nPermits write by owner<br \/>\n0100<br \/>\nPermits execute or search by owner<br \/>\n0040<br \/>\nPermits read by group<br \/>\n0020<br \/>\nPermits write by group<br \/>\n0010<br \/>\nPermits execute or search by group<br \/>\n0004<br \/>\nPermits read by others<br \/>\n0002<br \/>\nPermits write by others<br \/>\n0001<br \/>\nPermits execute or search by others<\/p>\n<p>Setting Traps<br \/>\nWhen a program is terminated before it would normally end, we can catch an exit signal. This is called a trap.<\/p>\n<p>Exit Signals<\/p>\n<p>0<br \/>\nNormal termination, end of script<br \/>\n1<br \/>\nHang up, line disconnected<br \/>\n2<br \/>\nTerminal interrupt, usually CONTROL-C<br \/>\n3<br \/>\nQuit key, child processes to die before terminating<br \/>\n9<br \/>\nkill -9 command, cannot trap this type of exit status<br \/>\n15<br \/>\nkill command\u2019s default action<br \/>\n24<br \/>\nStop, usually CONTROL-z<\/p>\n<p>Uppercase or Lowercase Text<br \/>\nVARIABLE VALUES<br \/>\nExpected input: TRUE<br \/>\nReal input: TRUE<br \/>\nPossible input: true TRUE True True, etc&#8230;<br \/>\nUPCASING<br \/>\nUPCASEVAR=$(echo $VARIABLE | tr \u2018[a-z]\u2019 \u2018[A-Z]\u2019)<br \/>\nDOWNCASING<br \/>\nDOWNCASEVAR=$(echo $VARIABLE | tr \u2018[A-Z]\u2019 \u2018[a-z]\u2019)<br \/>\n\u2018[a-z]\u2019 \u2018[A-Z]\u2019 Used for lower to uppercase<br \/>\n\u2018[A-Z]\u2019 \u2018[a-z]\u2019 Used for upper to lowercase<\/p>\n<p>Typeset -u VARIABLE: The -u switch to the typeset command is used for uppercase.<br \/>\nExample: EXAMPLE:<br \/>\nTypeset -u VARIABLE<br \/>\nVARIABLE=\u201dTrue\u201d<br \/>\necho $VARIABLE<br \/>\nTRUE<br \/>\nTypeset -l VARIABLE: always translate characters to lowercase<br \/>\nExample:<br \/>\n            Typeset -l VARIABLE<br \/>\nVARIABLE=\u201dTrue\u201d<br \/>\necho $VARIABLE<br \/>\ntrue<\/p>\n<p>Cron Tables<\/p>\n<p>15    3    8   1 * \/usr\/local\/bin\/somescript.sh<br \/>\n  |<br \/>\nMinute (0 through 29)<br \/>\nHour (0 through 23)<br \/>\nDay of the Month (1 through 31)<br \/>\nMonth (1 through 12)<br \/>\nWeekday (0 &#8211; 6 for Sunday to Saturday)<\/p>\n<p>at Command<\/p>\n<p>Like a cron table, the at command executes commands based on time. Using the at command we can schedule a job to run once, at a specific time.<\/p>\n<p>Silent Running<\/p>\n<p>To execute a script in silent mode (without any output to the screen), we can use the following syntax:<br \/>\n\/PATH\/script_name 2>&#038;1 > \/dev\/null<br \/>\nGetopts<\/p>\n<p>The getopts command is built in to the Korn shell. It retrieves valid command-line options specified by a single character preceded by a &#8211; (minus sign) or + (plus sign). To specify that a command switch requires an argument to the switch, it is followed by a : (colon). If the switch does not require any argument then the : should be omitted. All of the options put together are called the OptionString, and this is followed by some variable name. The argument for each switch is stored in a variable called $OPTARG. If the entire OptionString is preceded by a : (colon), then any unmatched switch option causes a ? to be loaded into the VARIABLE.<\/p>\n<p>Example:<\/p>\n<p>  SECS=0                                                      # Initialize all to zero<br \/>\nMINUTES=0<br \/>\nHOURS=0<br \/>\nDAYS=0<br \/>\nPROCESS=                                                   # Initialize to null<br \/>\nwhile getopts :s:m:h:d:p: TIMED 2>\/dev\/null<br \/>\ndo<br \/>\ncase $TIMED in<br \/>\ns) SECS=$OPTARG<br \/>\n;;<br \/>\nm) (( MINUTES = $OPTARG * 60 ))<br \/>\n;;<br \/>\nh) (( HOURS = $OPTARG * 3600 ))<br \/>\n;;<br \/>\nd) (( DAYS = $OPTARG * 86400 ))<br \/>\n;;<br \/>\np) PROCESS=$OPTARG<br \/>\n;;<br \/>\n\\?) usage<br \/>\nexit 1<br \/>\n;;<br \/>\nesac<br \/>\ndone<br \/>\n(( TOTAL_SECONDS = SECONDS + MINUTES + HOURS + DAYS ))<\/p>\n","protected":false},"excerpt":{"rendered":"<p>UNIX Shell Scripting<\/p>\n<p>The basic concept of a shell script is a list of commands, which are listed in the order of execution. A good shell script will have comments, preceded by a pound sign, #, describing the steps. There are conditional tests, such as value A is greater than value B, loops allowing us [&#8230;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[47],"tags":[],"_links":{"self":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/3272"}],"collection":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3272"}],"version-history":[{"count":1,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/3272\/revisions"}],"predecessor-version":[{"id":3273,"href":"https:\/\/mohan.sg\/index.php?rest_route=\/wp\/v2\/posts\/3272\/revisions\/3273"}],"wp:attachment":[{"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3272"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3272"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mohan.sg\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3272"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}