{"id":2131,"date":"2015-03-10T08:38:37","date_gmt":"2015-03-10T08:38:37","guid":{"rendered":"http:\/\/kedar.nitty-witty.com\/?p=2131"},"modified":"2023-04-27T13:25:59","modified_gmt":"2023-04-27T13:25:59","slug":"10-useful-shell-script-code-snippets-linux","status":"publish","type":"post","link":"https:\/\/kedar.nitty-witty.com\/blog\/10-useful-shell-script-code-snippets-linux","title":{"rendered":"10 useful shell script code snippets | Linux"},"content":{"rendered":"\n<p>This post is collection of 10 useful unix \/ linux shell script code snippets I&#8217;ve often used.<\/p>\n\n\n\n<p>Following these code snippet you will be able to answer following questions:<br>1. How to calculate script run-time in shell.<br>2. How to parse parameters \/ arguments to shell script.<br>3. How to safely change a directory in shell script.<br>4. How to check if a command was successful in shell script.<br>5. How to add timestamps in script log output.<br>6. How to check if a process is running.<br>7. How to colour your script output.<br>8. How to read variables from config file.<br>9. How to loop over files in a folder.<br>10. How to perform actions based on variable value using SWITCH&#8230;CASE<\/p>\n\n\n\n<p>And a bonus snippet<br>11: How to send emails from shell script.<\/p>\n\n\n\n<p>Let&#8217;s begin.<br><\/p>\n\n\n\n<!--more Continue Reading...-->\n\n\n\n<h1 class=\"wp-block-heading\">1. Snippet for calculating script run-time:<\/h1>\n\n\n\n<p>It&#8217;s always good to note the script duration and having knowledge of the run-time. Following is the code snippet for noting the script execution time.<\/p>\n\n\n\n<p>Add this to the beginning of the script:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">START=$(date +%s)\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Add following at the end or exit location:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">END=$(date +%s)\nDIFF=$(( $END - $START ))\nDIFF=$(( $DIFF \/ 60 ))\n<\/pre>\n<\/blockquote>\n\n\n\n<p>$DIFF will give you the runtime of the script in minutes.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">2. Parsing &amp; processing script parameters \/ arguments:<\/h1>\n\n\n\n<p>Scripts are often required to have user inputs in terms of arguments passed after script. Below code snippet is a simple method to capture the arguments passed.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">while [ \"$1\" != \"\" ]; do\n    case $1 in\n        -s  )   shift\t\n\t\tSERVER=$1 ;;  \n        -d  )   shift\n\t\tDATE=$1 ;;\n\t--paramter|p ) shift\n\t\tPARAMETER=$1;;\n        -h|help  )   usage # function call\n                exit ;;\n        * )     usage # All other parameters\n                exit 1\n    esac\n    shift\ndone\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Above snippet in shell script paramter_test.sh will behave as follows:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">sh parameter_test.sh -s myserver -d 20151225 --parameter SomeValue\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Though we may need to check for correctness of input or mandatory parameters; using say a parser function.<br># Confirm the mandatory parameters<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">if [ -z $SERVER ] || [ -z $DATE ]; then\n\techo \"Please specify both server and date\";\n\texit 1;\nfi;\n<\/pre>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">3. Change directory before processing your script:<\/h1>\n\n\n\n<p>Sanitizing &amp; verifying the directory status is very important before progressing the script. You do not want to mistakenly execute the commands in a wrong directory. We should verify if directory is present and have sufficient permission for the user.<br>Following code snippet takes care of the same.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">changedir()\n{\n\tDIR_NAME=$1\n\t# Check if the directory exist?\n\t[ -d \"$DIR_NAME\" ] || {\n\t\techo Dir: $DIR_NAME does not exist \n\t\texit 1\n\t}\n\n\t# Check if the directory is readable\n\t[ -r \"$DIR_NAME\" ] || {\n\t\techo Dir: $DIR_NAME not readable\n\t\texit 2\n\t}\n\n\t# Check if we have execute perms on directory\n\t[ -x \"$DIR_NAME\" ] || {\n\t\techo Dir: cannot cd to $DIR_NAME\n\t\texit 3\n\t}\n\n\t# Check if the directory is writable\n\t[ -w \"$DIR_NAME\" ] || {\n\t\techo Dir: $DIR_NAME not writeable\n\t\texit 4\n\t}\n\n\tcd $DIR_NAME\n\techo \"Present directory $DIR_NAME\"\n}\n<\/pre>\n<\/blockquote>\n\n\n\n<p>To safely change the directory call the function as follows:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">changedir \/data\/app\/\n<\/pre>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">4. Verifying if previous command was successful<\/h1>\n\n\n\n<p>When a processing of command depends on success or failure of previous command we can use the exit status. It can be checked using $?.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">if [ $? -ne 0 ]; then\n\techo \"The command was not successful.\";\n\t#do the needful \/ exit\nfi;\n<\/pre>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">5. Generating script logs with timestamp<\/h1>\n\n\n\n<p>Just as the duration of script it&#8217;s useful to have timestampped log. Use following function to log time for every output.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">log() {\n     echo [`date +%Y-%m-%d\\ %H:%M:%S`] $*\n}\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Call the function as follows instead of simply &#8220;echo&#8221;ing.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">log \"my string to be logged\"\n<\/pre>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">6. Checking if process is running:<\/h1>\n\n\n\n<p>This code snippet is used often when a script progress requires the known status of any particular system process.<br>A usual scenario say we need MySQL down before progressing further in script, we will use following shell function.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\"># Define shell function\ncheck_process() {\n\techo \"Checking if process $1 exists...\"\n\t[ \"$1\" = \"\" ]  &amp;&amp; return 0\n\tPROCESS_NUM=$(ps -ef | grep \"$1\" | grep -v \"grep\" | wc -l)\n\tif [ $PROCESS_NUM -ge 1 ];\n\tthen\n\t        return 1\n\telse\n\t        return 0\n\tfi\n}\n<\/pre>\n<\/blockquote>\n\n\n\n<p># Check for MySQL process and make the decision<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">check_process mysql;\nCHECK_RET=$?;\nif [ $CHECK_RET -ne 0 ]; \n\t# code block for process exists \nelse\n\t# code block for process not present\nfi;\n<\/pre>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">7. Colouring your script output<\/h1>\n\n\n\n<p>A readable and formatted output is good to have. Following code snippet helps you beautify your script output, colorizing or highlighting them.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">Define variables:\ntxtund=$(tput sgr 0 1)    # Underline\ntxtbld=$(tput bold)       # Bold\ntxtred=$(tput setaf 1)    # Red\ntxtgrn=$(tput setaf 2)    # Green\ntxtylw=$(tput setaf 3)    # Yellow\ntxtblu=$(tput setaf 4)    # Blue\ntxtpur=$(tput setaf 5)    # Purple\ntxtcyn=$(tput setaf 6)    # Cyan\ntxtwht=$(tput setaf 7)    # White\ntxtrst=$(tput sgr0)       # Text reset\n\nUse them as:\necho \"${txtbld}This is bold text output from shell script${txtrst}\"\necho \"${txtred}This is coloured red except ${txtblu}this is blue${txtrst}\"\n\n${txtrst} will reset the terminal.\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Refer: <a href=\"http:\/\/kedar.nitty-witty.com\/how-to-echo-colored-text-in-shell-script\" target=\"_blank\" rel=\"noopener\" title=\"\">http:\/\/kedar.nitty-witty.com\/how-to-echo-colored-text-in-shell-script<\/a><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">8. Reading variables from config file<\/h1>\n\n\n\n<p>Create a config file with contents as follows:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">key1=value1\nkey2=value2\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Add following line in the beginning of the shell script:<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">. configfile\n<\/pre>\n<\/blockquote>\n\n\n\n<p>This will load the key value pairs and you may verify &amp; access the values as $key1 or $key2.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">9. Looping over files in a folder<\/h1>\n\n\n\n<p>Below code snippet is quite simple as a concept of FOR loop we might need to loop over the files to perform operations.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">#!\/bin\/bash\nPATH=\/path\/to\/dir\/\nFILES=*.sql\nfor f in $PATH$FILES\ndo\n\t# Code block for processing each file $f\ndone\n<\/pre>\n<\/blockquote>\n\n\n\n<h1 class=\"wp-block-heading\">10. Using SWITCH&#8230;CASE<\/h1>\n\n\n\n<p>Following code snippet is a SWITCH&#8230;CASE for shell script often used for taking actions based on variable value.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\">\tcase $VARIABLE in\n\t\tVALUE-1) # CODE BLOCK FOR VALUE-1\n\t\t\t;;\n\n\t\tVALUE-2|VALUE-3) \n\t\t\t# CODE BLOCK FOR VALUE-2 OR VALUE-3\n\t\t \t;;\n\n\t\t*) echo \"Wrong option, exiting.\";;\n\tesac\n<\/pre>\n<\/blockquote>\n\n\n\n<p>(Bonus solution to &#8211; how-to-send-email worries!)<\/p>\n\n\n\n<h1 class=\"wp-block-heading\">11. The sendEmail Function<\/h1>\n\n\n\n<p>Following is the ready to use sendEmail function for your shell scripts. You may put the function definition in the beginning of your shell script and use to send emails.<br>All you need to set is variable values for email-content ($content), email-subject ($subject) and email-list ($email_list). Rest is only making a call to the function (sendEmail).<br>This handy function also notes the script runtime.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<pre class=\"wp-block-preformatted\"># sendEmail Function - mail &amp; exit.\nSTART=$(date +%s)\nsendEmail() {\n\tscripttime=0;\n\tEND=$(date +%s)\n\tDIFF=$(( $END - $START ))\n\tif [ $DIFF -le 60 ]; then\n\t\tscripttime=\"$DIFF seconds.\";\n\telse\n\t\tDIFF=$(( $DIFF \/ 60 ))\n\t\tscripttime=\"$DIFF minutes.\";\n\tfi;\n\tcontent=\"$content. Exec Time: $scripttime\"\n\techo $content | mail -s \"$subject\" $email_list\n\texit;\n}\n# sendEmail Function - end.\n<\/pre>\n<\/blockquote>\n\n\n\n<p>Hope this helps.<\/p>\n","protected":false},"excerpt":{"rendered":"10+ useful code snippets of Linux shell scripts for how-to color, sendmail, log, change dir, parse parameters, loop, configuration file, switch..case and more.\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[6],"tags":[393,59,394,102,395,105],"class_list":{"0":"post-2131","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-technical","7":"tag-code-snippets","8":"tag-linux","9":"tag-linux-scripting","10":"tag-script","11":"tag-shell-how-to","12":"tag-shell-script"},"aioseo_notices":[],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/posts\/2131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/comments?post=2131"}],"version-history":[{"count":11,"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/posts\/2131\/revisions"}],"predecessor-version":[{"id":2840,"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/posts\/2131\/revisions\/2840"}],"wp:attachment":[{"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/media?parent=2131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/categories?post=2131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/kedar.nitty-witty.com\/blog\/wp-json\/wp\/v2\/tags?post=2131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}