{"id":35,"date":"2018-10-21T08:00:00","date_gmt":"2018-10-21T00:00:00","guid":{"rendered":""},"modified":"2018-11-11T16:10:58","modified_gmt":"2018-11-11T08:10:58","slug":"the-linux-command-line-flow-control-part-3","status":"publish","type":"post","link":"https:\/\/yeslq.com\/?p=35","title":{"rendered":"The Linux Command Line&#8212;Flow Control &#8211; Part 3"},"content":{"rendered":"<h1 style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif; font-weight: normal;\"><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;\"><\/p>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Now that you have learned about positional parameters, it is time to cover the remaining flow control statement,&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\"><a href=\"http:\/\/linuxcommand.org\/lc3_man_pages\/forh.html\" style=\"color: #002740;\">for<\/a><\/tt>. Like&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">while<\/tt>&nbsp;and&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">until<\/tt>,&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;is used to construct loops.&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;works 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;\"><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> variable <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> words; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>    commands<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><br \/>     <\/tt><br \/><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">In essence,&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;assigns a word from the list of words to the specified variable, executes the commands, and repeats this over and over until all the words have been used up. Here is an example:<\/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 \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> i <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> word1 word2 word3; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> $i<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><br \/>     <\/tt><br \/><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">In this example, the variable&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">i<\/tt>&nbsp;is assigned the string &#8220;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">word1<\/tt>&#8220;, then the statement&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">echo $i<\/tt>&nbsp;is executed, then the variable&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">i<\/tt>&nbsp;is assigned the string &#8220;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">word2<\/tt>&#8220;, and the statement&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">echo $i<\/tt>&nbsp;is executed, and so on, until all the words in the list of words have been assigned.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">The interesting thing about&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;is the many ways you can construct the list of words. All kinds of expansions can be used. In the next example, we will construct the list of words using command substitution:<\/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 \/>count=0<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> i <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> $(cat ~\/.bash_profile); <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>    count=$((count + 1))<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"Word $count ($i) contains $(echo -n $i | wc -c) characters\"<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><\/tt><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Here we take the file&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">.bash_profile<\/tt>&nbsp;and count the number of words in the file and the number of characters in each word.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">So what&#8217;s this got to do with positional parameters? Well, one of the features of&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;is that it can use the positional parameters as the list of words:<\/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 \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> i <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> \"$@\"; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> $i<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><\/tt><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">The shell variable&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">\"$@\"<\/tt>&nbsp;contains the list of command line arguments. This technique is often used to process a list of files on the command line. Here is a another example:<\/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 \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> filename <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> \"$@\"; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>    result=<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> -f \"$filename\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>        result=\"$filename is a regular file\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">else<\/tt><br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> -d \"$filename\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>            result=\"$filename is a directory\"<br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> -w \"$filename\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>        result=\"$result and it is writable\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">else<\/tt><br \/>        result=\"$result and it is not writable\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"$result\"<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><\/tt><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Try this script. Give it a list of files or a wildcard like &#8220;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">*<\/tt>&#8221; to see it work.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Here is another example script. This one compares the files in two directories and lists which files in the first directory are missing from the second.<\/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 \/># cmp_dir - program to compare two directories<br \/><br \/># Check for required arguments<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> $# -ne 2 <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"usage: $0 directory_1 directory_2\" 1&gt;&amp;2<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">exit<\/tt> 1<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/><br \/># Make sure both arguments are directories<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> ! -d $1 <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"$1 is not a directory!\" 1&gt;&amp;2<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">exit<\/tt> 1<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/><br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> ! -d $2 <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"$2 is not a directory!\" 1&gt;&amp;2<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">exit<\/tt> 1<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/><br \/># Process each file in directory_1, comparing it to directory_2<br \/>missing=0<br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> filename <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> $1\/*; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>    fn=$(basename \"$filename\")<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> -f \"$filename\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> ! -f \"$2\/$fn\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>            <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"$fn is missing from $2\"<br \/>            missing=$((missing + 1))<br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><br \/><tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"$missing files missing\"<\/tt><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Now on to the real work. We are going to improve the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">home_space<\/tt>&nbsp;function in our script to output more information. You will recall that our previous version looked 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;\">home_space()<br \/>{<br \/>    # Only the superuser can get this information<br \/><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> \"$(id -u)\" = \"0\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;h2&gt;Home directory space by user&lt;\/h2&gt;\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;pre&gt;\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"Bytes Directory\"<br \/>        du -s \/home\/* | sort -nr<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;\/pre&gt;\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/><br \/>}   # end of home_space<br \/>     <\/tt><br \/><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Here is the new version:<\/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;\">home_space()<br \/>{<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;h2&gt;Home directory space by user&lt;\/h2&gt;\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;pre&gt;\"<br \/>    format=\"%8s%10s%10s   %-sn\"<br \/>    printf \"$format\" \"Dirs\" \"Files\" \"Blocks\" \"Directory\"<br \/>    printf \"$format\" \"----\" \"-----\" \"------\" \"---------\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">[<\/tt> $(id -u) = \"0\" <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">];<\/tt> <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>        dir_list=\"\/home\/*\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">else<\/tt><br \/>        dir_list=$HOME<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> home_dir <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> $dir_list; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/>        total_dirs=$(find $home_dir -type d | wc -l)<br \/>        total_files=$(find $home_dir -type f | wc -l)<br \/>        total_blocks=$(du -s $home_dir)<br \/>        printf \"$format\" $total_dirs $total_files $total_blocks<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;\/pre&gt;\"<br \/><br \/>}   # end of home_space<\/tt><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">This improved version introduces a new command&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\"><a href=\"http:\/\/linuxcommand.org\/lc3_man_pages\/printf1.html\" style=\"color: #002740;\">printf<\/a><\/tt>, which is used to produce formatted output according to the contents of a&nbsp;<i>format string<\/i>.&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">printf<\/tt>comes from the C programming language and has been implemented in many other programming languages including C++, Perl, awk, java, PHP, and of course, bash. You can read more about&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">printf<\/tt>&nbsp;format strings at:<\/div>\n<ul style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">\n<li><a href=\"http:\/\/www.gnu.org\/software\/gawk\/manual\/html_node\/Control-Letters.html#Control-Letters\" style=\"color: #002740;\">GNU Awk User&#8217;s Guide &#8211; Control Letters<\/a><\/li>\n<li><a href=\"http:\/\/www.gnu.org\/software\/gawk\/manual\/html_node\/Format-Modifiers.html#Format-Modifiers\" style=\"color: #002740;\">GNU Awk User&#8217;s Guide &#8211; Format Modifiers<\/a><\/li>\n<\/ul>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">We also introduce the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\"><a href=\"http:\/\/linuxcommand.org\/man_pages\/find1.html\" style=\"color: #002740;\">find<\/a><\/tt>&nbsp;command.&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">find<\/tt>&nbsp;is used to search for files or directories that meet specific criteria. In the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">home_space<\/tt>&nbsp;function, we use&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">find<\/tt>&nbsp;to list the directories and regular files in each home directory. Using the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">wc<\/tt>&nbsp;command, we count the number of files and directories found.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">The really interesting thing about&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">home_space<\/tt>&nbsp;is how we deal with the problem of superuser access. You will notice that we test for the superuser with&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">id<\/tt>&nbsp;and, according to the outcome of the test, we assign different strings to the variable&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">dir_list<\/tt>, which becomes the list of words for the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;loop that follows. This way, if an ordinary user runs the script, only his\/her home directory will be listed.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Another function that can use a&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;loop is our unfinished&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">system_info<\/tt>&nbsp;function. We can build it 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 \/>    # Find any release files in \/etc<br \/><br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">if<\/tt> ls \/etc\/*release 1&gt;\/dev\/null 2&gt;&amp;1; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">then<\/tt><br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;h2&gt;System release info&lt;\/h2&gt;\"<br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;pre&gt;\"<br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt> i <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">in<\/tt> \/etc\/*release; <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">do<\/tt><br \/><br \/>            # Since we can't be sure of the<br \/>            # length of the file, only<br \/>            # display the first line.<br \/><br \/>            head -n 1 $i<br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">done<\/tt><br \/>        uname -orp<br \/>        <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">echo<\/tt> \"&lt;\/pre&gt;\"<br \/>    <tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">fi<\/tt><br \/><br \/>}   # end of system_info<\/tt><\/pre>\n<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">In this function, we first determine if there are any release files to process. The release files contain the name of the vendor and the version of the distribution. They are located in the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace;\">\/etc<\/tt>&nbsp;directory. To detect them, we perform an&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">ls<\/tt>&nbsp;command and throw away all of its output. We are only interested in the exit status. It will be true if any files are found.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Next, we output the HTML for this section of the page, since we now know that there are release files to process. To process the files, we start a&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\">for<\/tt>&nbsp;loop to act on each one. Inside the loop, we use the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\"><a href=\"http:\/\/linuxcommand.org\/lc3_man_pages\/head1.html\" style=\"color: #002740;\">head<\/a><\/tt>&nbsp;command to return the first line of each file.<\/div>\n<div style=\"background-color: white; font-family: verdana, arial, helvetica, sans-serif;\">Finally, we use the&nbsp;<tt style=\"font-family: courier, lucidatypewriter, monospace; font-weight: bold;\"><a href=\"http:\/\/linuxcommand.org\/lc3_man_pages\/uname1.html\" style=\"color: #002740;\">uname<\/a><\/tt>&nbsp;command with the &#8220;o&#8221;, &#8220;r&#8221;, and &#8220;p&#8221; options to obtain some additional information from the system.<\/div>\n<p><\/span><\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Linux Command Line&nbsp;by William Shotts Now that  &#8230; <a title=\"The Linux Command Line&#8212;Flow Control &#8211; Part 3\" class=\"read-more\" href=\"https:\/\/yeslq.com\/?p=35\" aria-label=\"\u9605\u8bfb The Linux Command Line&#8212;Flow Control &#8211; Part 3\">\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-35","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\/35","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=35"}],"version-history":[{"count":1,"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/posts\/35\/revisions"}],"predecessor-version":[{"id":96,"href":"https:\/\/yeslq.com\/index.php?rest_route=\/wp\/v2\/posts\/35\/revisions\/96"}],"wp:attachment":[{"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yeslq.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}