{"id":198,"date":"2020-08-18T19:23:47","date_gmt":"2020-08-18T20:23:47","guid":{"rendered":"http:\/\/www.linux-tutorial.info\/?page_id=77"},"modified":"2020-08-22T19:25:17","modified_gmt":"2020-08-22T20:25:17","slug":"this-is-the-page-title-toplevel-32","status":"publish","type":"page","link":"http:\/\/www.linux-tutorial.info\/?page_id=198","title":{"rendered":"Basic Shell Scripting"},"content":{"rendered":"\n<title>Basic Shell Scripting<\/title>\n<p>\nIn many of the other sections of the shell and utilities, we talked about a\nfew  programming constructs that you could use to create a quick\n<glossary>script<\/glossary> to perform some complex task. What if you wanted to\nrepeat that task with different parameters each time? One simple solution is\nto is to re-type everything each time. Obviously not a happy thing.\n<\/p>\n<p>\nThe solution is to create a shell script we can use over and over again, which\nis the topic of this section. There are entire books on shell programming and to understand\neverything you probably need more material that any single book can provide. Rather\nthan going through every possible shell constructs, we are going to cover more or\nless the basics. One of the things we will be using as a guide is how often a given\nconstruct appears in shell scripts that a standard Linux distribution provides by default\nand how important these constructs are to understanding the given script.\n<\/p>\n<p>\nTo create a shell script, we could use <command>vi<\/command> or some other text editor\nto create the file. However, we could\ntake advantage of a characteristic of the <command>cat<\/command> command, which is normally used to\noutput the contents of a file to the screen. You can also redirect the <command>cat<\/command>  to\nanother file.\n<\/p>\n<p>\nIf we wanted to combine the contents of a file, we could do something like this:<\/p>\n<p>\n<commandexample command=\"cat\">cat file1 file2 file3 &gt;newfile<\/commandexample>\n<\/p>\n<p>\nThis would combine file1, file2, and file3 into newfile.\n<\/p>\n<p>\nWhat happens if we leave the names of the source files out? In this\ninstance, our command would look like this:<\/p>\n<p>\n<commandexample command=\"cat\">cat > newfile<\/commandexample>\n<\/p>\n<p>\nNow, cat will take its input from the default input file, <glossary>stdin<\/glossary>.\nWe can now type in lines, one at a time. When we are done, we tell cat to close\nthe file by sending it an end-of-file character, <keyinput>Ctrl-D<\/keyinput>. So,\nto create the new command, we would issue the <command>cat<\/command> command as\nabove and type in our command as the following:\n<\/p>\n<p>\n<commandexample command=\"bash\">\nfor j in boat ship yacht\ndo\nfind .\/letters\/taxes -type f | xargs grep -i $j\ndone\n<\/commandexample>\n<keyinput>&lt;CTRL-D&gt;<keyinput>\n<\/p>\n<p>\nNote that here the secondary prompt, &gt;, does not appear because it is cat\nthat is reading our input and not the <glossary>shell<\/glossary>.\nWe now have a file containing the five lines that we typed in that we can use\nas a <glossary>shell<\/glossary> script. So, being able to create new scripts with\nthe <command>cat<\/command>.\n<\/p>\n<p>\nGranted to be able to edit the file\nusing <command>vi<\/command> is fairly straight forward. However, I have worked on\na number of systems were vi was disabled for everyone but the administrator or I\naccessed the machine through a connection that made using <command>vi<\/command>\ndifficult.\n<\/p>\n<p>\nIn order to fully understand this we need to look at the for-in construct and the\ndo-done pair. You will find the do-done pair in a number of contexts. In short,\nit defines the block of commands to be executed by the preceeding construct. In\nthis case the for-in construct. You will also find a do-done pair when creating loops\nusing while, as well as other places.\n<\/p>\n<p>\nIn the example above, the for-in construct looked like this:\n<commandexample command=\"bash\">\nfor j in boat ship yacht\n<\/commandexample>\n<\/p>\n<question id=\"\" type=\"mc\" text=\"What shell construct would you use to create a block that\nloops through a pre-defined set of values?\" \/>\n<p>\nIn essence this loops through the statements in the do-done block once for each of\nthe values listed: boat ship yacht. Each time through the loop, the respective\nvalue is assigned to the variable j. So, the first time j=boot, the second time\nj=ship and the third time j=yacht.\n<\/p>\n<p>\nWe did not need to use a single letter here. Instead, we could have used any valid\nvariable. For example, we could have called it SEARCHWORD, if we wanted.\n<\/p>\n<p>\nIn our example, the lines within the do-done block are executed three times. Here we only\nhave a single line, but could have essentially any number of lines within a do-done block.\n<\/p>\n<p>\nThis example also uses the <command>xargs<\/command> command. The example here is perhaps\nthe simplest form you will find <command>xargs<\/command>. As you can see, it is the end of\nthe <glossary>pipe<\/glossary> from the <command>find<\/command> which is simply finding every single\nfile in the directory <directory>.\/letters\/taxes<\/directory>. Thus, <command>xargs<\/command>\nis getting a list of files feed into it&#8217;s standard input. It then creates a command using\n<command>grep<\/command> which searches through each of the files passed through the pipe.\n<\/p>\n<p>\nKeep in mind that we have the variable $j which changes during each pass through the loop.\nSo, the first time through the look the <command>xargs<\/command> command would look\nlike this:\n<\/p>\n<p>\n<commandexample command=\"xargs\">\nxargs grep -i boot\n<\/commandexample>\n<\/p>\n<p>\nTherefore, this would search through each of the file looking for &#8220;boot&#8221;. Note that the -i says\nto ingore the case.\n<\/p>\n<concept id=\"\" description=\"The chmod command is used to change a file's permissions.\" \/>\n<concept id=\"27\" description=\"Use the 'chmod' command to make shell scripts executable.\" \/>\n<question id=\"\" type=\"mc\" text=\"What command is used to change a file's permissions?\" \/>\n<p>\nHowever, right now, all that we have is a file named <file>newfile<\/file> that contains\nfive lines. We need to tell the system that it is a <glossary>shell<\/glossary>\nscript that can be\nexecuted. Remember in our discussion on <glossary>operating system<\/glossary>\nbasics that I said that a file&#8217;s <glossary>permissions<\/glossary>\nneed to be set to be able to execute the file. To change the\npermissions, we need a new command: <\/command>chmod<\/command>.\n(Read as &#8220;change mode&#8221; because we are changing the mode of the file.)\n<\/p>\n<concept id=\"\" description=\"The chmod command is used to change a file's mode and thus make it executable.\" \/>\n<question id=\"\" type=\"mc\" text=\"What command is used to change a file's mode and thus make it executable?\" \/>\n<p>\nThe <\/command>chmod<\/command> command is used to not only change access to a\nfile, but also to tell the system that it should <em>try<\/em> to execute the\ncommand. I said &#8220;try&#8221; because the system would read that file, line-by-line,\nand would try to execute each line. If we typed in some garbage in a <glossary>shell<\/glossary>\nscript, the system would try to execute each line and would probably report &#8220;not found&#8221; for every line.\n<\/p>\n<concept id=\"\" description=\"To make a file execute properly, you need to give it execute permissions.\" \/>\n<question id=\"\" type=\"mc\" text=\"Which command would make the file scripts.sh executable?\" \/>\n<p>\nTo make a file execute properly, we need to give it execute <glossary>permissions<\/glossary>.\nTo give everyone execution <glossary>permissions<\/glossary>, you use the\n<\/command>chmod<\/command> command like this:\n<\/p>\n<p>\n<commandexample command=\"chmod\">chmod +x newfile<\/commandexample>\n<\/p>\n<concept id=\"\" description=\"A script script needs to be readable by the person trying to execute it.\" \/>\n<question id=\"\" type=\"TF\" text=\"A script script needs to be readable by the person trying to execute it.\" \/>\n<p>\nNow the file <file>newfile<\/file> has execute <glossary>permissions<\/glossary>, so, in a sense,\nit is executable. However, remember that I said that with a shell scripts, the system would\nread each line and try to parse it. In order for a <glossary>shell<\/glossary>\nscript to function correctly, it also needs to be readable by\nthe person executing it. In order to read a file, you need to have read\npermission on that file. More than likely, <em>you<\/em> already have read\npermissions on the file since you created it. However, since we gave everyone\nexecution <glossary>permissions<\/glossary>, let&#8217;s give them all read permissions as\nwell, like this:<\/p>\n<p>\n<commandexample command=\"chmod\">chmod +r newfile<\/commandexample>\n<\/p>\n<p>\nYou now have a new command called <file>newfile<\/file>. This can be executed just like\nany the system provides for you. If that file resides in a directory somewhere\nin your path, all you need to do is type it in. Otherwise, (as we talked about\nbefore) you need to enter in the path as well. Keep in mind that the system does\nnot need to be able to read <glossary>binary<\/glossary>\nprograms. All it needs to be able to do is\nexecute them. Now you have your first <glossary>shell<\/glossary>\nscript and your first self-written Linux command.\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Basic Shell Scripting In many of the other sections of the shell and utilities, we talked about a few programming constructs that you could use to create a quick script to perform some complex task. What if you wanted to &hellip; <a href=\"http:\/\/www.linux-tutorial.info\/?page_id=198\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-198","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/198","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=198"}],"version-history":[{"count":1,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/198\/revisions"}],"predecessor-version":[{"id":507,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/198\/revisions\/507"}],"wp:attachment":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=198"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}