{"id":42,"date":"2018-10-17T18:00:00","date_gmt":"2018-10-17T10:00:00","guid":{"rendered":""},"modified":"2018-11-11T16:10:59","modified_gmt":"2018-11-11T08:10:59","slug":"the-linux-command-line-shell-functions","status":"publish","type":"post","link":"https:\/\/yeslq.com\/?p=42","title":{"rendered":"The Linux Command Line&#8212;Shell Functions"},"content":{"rendered":"<p><\/p>\n<div style=\"-webkit-text-stroke-width: 0px; color: black; font-family: &quot;Microsoft YaHei&quot;; font-size: medium; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;\"><\/div>\n<p><\/p>\n<h1 style=\"-webkit-text-stroke-width: 0px; background-color: white; color: black; font-family: verdana, arial, helvetica, sans-serif; font-style: normal; font-variant-caps: normal; font-variant-ligatures: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: start; text-decoration-color: initial; text-decoration-style: initial; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px;\"><i style=\"font-size: x-small;\"><a href=\"http:\/\/linuxcommand.org\/tlcl.php\" style=\"color: #002740;\">The Linux Command Line&nbsp;<\/a><\/i><span style=\"font-size: xx-small;\">by William Shotts<\/span><\/h1>\n<div><span style=\"font-size: xx-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-size: xx-small;\"><\/span><\/p>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\"><span style=\"font-size: xx-small;\">As programs get longer and more complex, they become more difficult to design, code, and maintain. As with any large endeavor, it is often useful to break a single, large task into a series of smaller tasks.<\/span><\/div>\n<p><span style=\"font-size: xx-small;\"><\/span><\/p>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\"><span style=\"font-size: xx-small;\">In this lesson, we will begin to break our single monolithic script into a number of separate functions.<\/span><\/div>\n<p><span style=\"font-size: xx-small;\"><\/p>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">To get familiar with this idea, let&#8217;s consider the description of an everyday task &#8212; going to the market to buy food. Imagine that we were going to describe the task to a man from Mars.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Our first top-level description might look like this:<\/div>\n<ol style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">\n<li>Leave house<\/li>\n<li>Drive to market<\/li>\n<li>Park car<\/li>\n<li>Enter market<\/li>\n<li>Purchase food<\/li>\n<li>Drive home<\/li>\n<li>Park car<\/li>\n<li>Enter house<\/li>\n<\/ol>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">This description covers the overall process of going to the market; however a man from Mars will probably require additional detail. For example, the &#8220;Park car&#8221; sub task could be described as follows:<\/div>\n<ol style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">\n<li>Find parking space<\/li>\n<li>Drive car into space<\/li>\n<li>Turn off motor<\/li>\n<li>Set parking brake<\/li>\n<li>Exit car<\/li>\n<li>Lock car<\/li>\n<\/ol>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Of course the task &#8220;Turn off motor&#8221; has a number of steps such as &#8220;turn off ignition&#8221; and &#8220;remove key from ignition switch,&#8221; and so on.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">This process of identifying the top-level steps and developing increasingly detailed views of those steps is called&nbsp;<i>top-down design<\/i>. This technique allows you to break large complex tasks into many small, simple tasks.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">As our script continues to grow, we will use top down design to help us plan and code our script.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">If we look at our script&#8217;s top-level tasks, we find the following list:<\/div>\n<ol style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">\n<li>Open page<\/li>\n<li>Open head section<\/li>\n<li>Write title<\/li>\n<li>Close head section<\/li>\n<li>Open body section<\/li>\n<li>Write title<\/li>\n<li>Write time stamp<\/li>\n<li>Close body section<\/li>\n<li>Close page<\/li>\n<\/ol>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">All of these tasks are implemented, but we want to add more. Let&#8217;s insert some additional tasks after task 7:<\/div>\n<ol start=\"7\" style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">\n<li>Write time stamp<\/li>\n<li>Write system release info<\/li>\n<li>Write up-time<\/li>\n<li>Write drive space<\/li>\n<li>Write home space<\/li>\n<li>Close body section<\/li>\n<li>Close page<\/li>\n<\/ol>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">It would be great if there were commands that performed these additional tasks. If there were, we could use command substitution to place them in our script like so:<\/div>\n<div style=\"background-color: #e0e0e0; font-family: verdana, arial, helvetica, sans-serif; padding: 0.5em;\">\n<pre style=\"font-family: courier, lucidatypewriter, monospace;\"><tt style=\"font-family: courier, lucidatypewriter, monospace;\">#!\/bin\/bash<br \/><br \/># sysinfo_page - A script to produce a system information HTML file<br \/><br \/>##### Constants<br \/><br \/>TITLE=\"System Information for $HOSTNAME\"<br \/>RIGHT_NOW=$(date +\"%x %r %Z\")<br \/>TIME_STAMP=\"Updated on $RIGHT_NOW by $USER\"<br \/><br \/>##### Main<br \/><br \/>cat &lt;&lt;- _EOF_<br \/>  &lt;html&gt;<br \/>  &lt;head&gt;<br \/>      &lt;title&gt;$TITLE&lt;\/title&gt;<br \/>  &lt;\/head&gt;<br \/><br \/>  &lt;body&gt;<br \/>      &lt;h1&gt;$TITLE&lt;\/h1&gt;<br \/>      &lt;p&gt;$TIME_STAMP&lt;\/p&gt;<br \/>      $(system_info)<br \/>      $(show_uptime)<br \/>      $(drive_space)<br \/>      $(home_space)<br \/>  &lt;\/body&gt;<br \/>  &lt;\/html&gt;<br \/>_EOF_<br \/>       <\/tt><br \/><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">While there are no commands that do exactly what we need, we can create them using&nbsp;<i>shell functions<\/i>.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">As we learned in lesson 2, shell functions act as &#8220;little programs within programs&#8221; and allow us to follow top-down design principles. To add the shell functions to our script, we change it so:<\/div>\n<div style=\"background-color: #e0e0e0; font-family: verdana, arial, helvetica, sans-serif; padding: 0.5em;\">\n<pre style=\"font-family: courier, lucidatypewriter, monospace;\"><tt style=\"font-family: courier, lucidatypewriter, monospace;\">#!\/bin\/bash<br \/><br \/># sysinfo_page - A script to produce an system information HTML file<br \/><br \/>##### Constants<br \/><br \/>TITLE=\"System Information for $HOSTNAME\"<br \/>RIGHT_NOW=$(date +\"%x %r %Z\")<br \/>TIME_STAMP=\"Updated on $RIGHT_NOW by $USER\"<br \/><br \/>##### Functions<br \/><br \/>system_info()<br \/>{<br \/><br \/>}<br \/><br \/><br \/>show_uptime()<br \/>{<br \/><br \/>}<br \/><br \/><br \/>drive_space()<br \/>{<br \/><br \/>}<br \/><br \/><br \/>home_space()<br \/>{<br \/><br \/>}<br \/><br \/>##### Main<br \/><br \/>cat &lt;&lt;- _EOF_<br \/>  &lt;html&gt;<br \/>  &lt;head&gt;<br \/>      &lt;title&gt;$TITLE&lt;\/title&gt;<br \/>  &lt;\/head&gt;<br \/><br \/>  &lt;body&gt;<br \/>      &lt;h1&gt;$TITLE&lt;\/h1&gt;<br \/>      &lt;p&gt;$TIME_STAMP&lt;\/p&gt;<br \/>      $(system_info)<br \/>      $(show_uptime)<br \/>      $(drive_space)<br \/>      $(home_space)<br \/>  &lt;\/body&gt;<br \/>  &lt;\/html&gt;<br \/>_EOF_<br \/>       <\/tt><br \/><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">A couple of important points about functions: First, they must appear before you attempt to use them. Second, the function body (the portions of the function between the { and } characters) must contain at least one valid command. As written, the script will not execute without error, because the function bodies are empty. The simple way to fix this is to place a&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">return<\/tt>&nbsp;statement in each function body. After you do this, our script will execute successfully again.<\/div>\n<h2 style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-weight: normal;\">Keep Your Scripts Working<\/h2>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">When you are developing a program, it is is often a good practice to add a small amount of code, run the script, add some more code, run the script, and so on. This way, if you introduce a mistake into your code, it will be easier to find and correct.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">As you add functions to your script, you can also use a technique called&nbsp;<i>stubbing<\/i>&nbsp;to help watch the logic of your script develop. Stubbing works like this: imagine that we are going to create a function called &#8220;system_info&#8221; but we haven&#8217;t figured out all of the details of its code yet. Rather than hold up the development of the script until we are finished with system_info, we just add an&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt>&nbsp;command like this:<\/div>\n<div style=\"background-color: #e0e0e0; font-family: verdana, arial, helvetica, sans-serif; padding: 0.5em;\">\n<pre style=\"font-family: courier, lucidatypewriter, monospace;\"><tt style=\"font-family: courier, lucidatypewriter, monospace;\">system_info()<br \/>{<br \/>    # Temporary function stub<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"function system_info\"<br \/>}<br \/>       <\/tt><br \/><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">This way, our script will still execute successfully, even though we do not yet have a finished system_info function. We will later replace the temporary stubbing code with the complete working version.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">The reason we use an&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt>&nbsp;command is so we get some feedback from the script to indicate that the functions are being executed.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Let&#8217;s go ahead and write stubs for our new functions and keep the script working.<\/div>\n<div style=\"background-color: #e0e0e0; font-family: verdana, arial, helvetica, sans-serif; padding: 0.5em;\">\n<pre style=\"font-family: courier, lucidatypewriter, monospace;\"><tt style=\"font-family: courier, lucidatypewriter, monospace;\">#!\/bin\/bash<br \/><br \/># sysinfo_page - A script to produce an system information HTML file<br \/><br \/>##### Constants<br \/><br \/>TITLE=\"System Information for $HOSTNAME\"<br \/>RIGHT_NOW=$(date +\"%x %r %Z\")<br \/>TIME_STAMP=\"Updated on $RIGHT_NOW by $USER\"<br \/><br \/>##### Functions<br \/><br \/>system_info()<br \/>{<br \/>    # Temporary function stub<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"function system_info\"<br \/>}<br \/><br \/><br \/>show_uptime()<br \/>{<br \/>    # Temporary function stub<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"function show_uptime\"<br \/>}<br \/><br \/><br \/>drive_space()<br \/>{<br \/>    # Temporary function stub<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"function drive_space\"<br \/>}<br \/><br \/><br \/>home_space()<br \/>{<br \/>    # Temporary function stub<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"function home_space\"<br \/>}<br \/><br \/><br \/>##### Main<br \/><br \/>cat &lt;&lt;- _EOF_<br \/>  &lt;html&gt;<br \/>  &lt;head&gt;<br \/>      &lt;title&gt;$TITLE&lt;\/title&gt;<br \/>  &lt;\/head&gt;<br \/><br \/>  &lt;body&gt;<br \/>      &lt;h1&gt;$TITLE&lt;\/h1&gt;<br \/>      &lt;p&gt;$TIME_STAMP&lt;\/p&gt;<br \/>      $(system_info)<br \/>      $(show_uptime)<br \/>      $(drive_space)<br \/>      $(home_space)<br \/>  &lt;\/body&gt;<br \/>  &lt;\/html&gt;<br \/>_EOF_<br \/>       <\/tt><\/pre>\n<\/div>\n<p><\/span><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Linux Command Line&nbsp;by William Shotts As progra &#8230; <a title=\"The Linux Command Line&#8212;Shell Functions\" class=\"read-more\" href=\"https:\/\/yeslq.com\/?p=42\" aria-label=\"\u9605\u8bfb The Linux Command Line&#8212;Shell Functions\">\u9605\u8bfb\u66f4\u591a<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,4,6],"tags":[],"class_list":["post-42","post","type-post","status-publish","format-standard","hentry","category-linux","category-shell","category-the-linux-command-line"],"_links":{"self":[{"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/posts\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=42"}],"version-history":[{"count":1,"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions"}],"predecessor-version":[{"id":103,"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/posts\/42\/revisions\/103"}],"wp:attachment":[{"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}