{"id":187,"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:26:02","modified_gmt":"2020-08-22T20:26:02","slug":"this-is-the-page-title-toplevel-21","status":"publish","type":"page","link":"http:\/\/www.linux-tutorial.info\/?page_id=187","title":{"rendered":"Interpreting the Command"},"content":{"rendered":"\n<title>Interpreting the Command<\/title>\n<p>\nWhen you input a <glossary>command-line<\/glossary>, the <glossary>shell<\/glossary> needs\nto be able intepret it correctly in order to know what exactly to do. Maybe you have\nmultiple options or redirect the output to a file. In any event the shell goes through\nseveral steps to figure out that needs to be done.\n<p>\n<p>\nOne question I had was, &#8220;In what order does everything get done?&#8221; We have\nshell variables to expand, maybe an <glossary>alias<\/glossary> or function to process,\n&#8220;real&#8221; commands,  pipes and input\/output <glossary>redirection<\/glossary>.\nThere are a lot of things that the shell\nmust consider when figuring out what to do and when.\n<\/p>\n<p>\nFor the most part, this is not very important. Commands do not get so complex\nthat knowing the evaluation order becomes an issue. However, on a few occasions\nI have run into situations in which things did not behave as I thought they\nshould. By evaluating the command myself (as the <glossary>shell<\/glossary>\nwould), it became clear what was happening. Let&#8217;s take a look.\n<\/p>\n<question id=\"49\" text=\"To be evaluated, commands are broken into what?\" \/>\n<concept id=\"96\" description=\"To be evaluated, commands are broken into 'tokens'.\" \/>\n<p>\nThe first thing that gets done is that the <glossary>shell<\/glossary>\nfigures out how many commands there are on the line. (Remember, you can separate multiple commands on\na single line with a semicolon.) This process determines how many\n<em>tokens<\/em> there are on the <glossary>command line<\/glossary>.\n In this context, a <glossary>token<\/glossary>\ncould be an entire command or it could be a control word such as &#8220;if.&#8221; Here, too, the\nshell must deal with input\/output <glossary>redirection<\/glossary>\nand pipes.\n<\/p>\n<p>\nOnce the <glossary>shell<\/glossary>\ndetermines how many tokens there are, it checks the syntax of\neach <glossary>token<\/glossary>.\n Should there be a syntax error, the <glossary>shell<\/glossary>\nwill not try to start\n<i>any<\/i> of the commands. If the syntax is correct, it begins interpreting the\ntokens.\n<\/p><br \/>\n<question id=\"453\" text=\"In what order are aliases, functions shell build-in commands and \"real\" commands evaluated by the shell?\" \/>\n<question id=\"454\" text=\"Aliases do not always represent commands and must therefore be evaluated before the shell tries to executed the command.\" \/>\n<concept id=\"213\" description=\"Aliases do not always represent commands and must therefore be evaluated before the shell tries to executed the command.\" \/>\n<p>\nFirst, any <glossary>alias<\/glossary> you might have is expanded. Aliases are\na way for some shells to allow you to define your own commands. If any\n<glossary>token<\/glossary> on the <glossary>command line<\/glossary>\nis actually an <glossary>alias<\/glossary> that you have defined, it is\nexpanded before the <glossary>shell<\/glossary> proceeds. If it\nhappens that an <glossary>alias<\/glossary> contains another alias, they are both expanded before\ncontinuing with the next step.\n<p>\nThe next thing the <glossary>shell<\/glossary>\nchecks for is functions. Like the functions in\nprogramming languages such as C, a <glossary>shell<\/glossary>\nfunction can be thought of as a small\nsubprogram. Check the other sections for details on\n<tutorial id=27>aliases<\/tutorial> and\n<tutorial id=25>functions<\/tutorial>.\n<\/p>\n<p>\nOnce aliases and functions have all been completely expanded, the shell\nevaluates variables. Finally, it uses any wildcards to expand them to file\nnames. This is done according to the rules we talked about previously.\n<\/p>\n<p>\nAfter the <glossary>shell<\/glossary>\nhas evaluated everything, it is <em>still<\/em> not ready to\nrun the command. It first checks to see if the first <glossary>token<\/glossary>\nrepresents a command built into the <glossary>shell<\/glossary>\nor an external one. If it&#8217;s not internal, the shell needs to\ngo through the <glossary>search path<\/glossary>.\n<\/p>\n<p>\nAt this point, it sets up the <glossary>redirection<\/glossary>,\n including the pipes. These\nobviously must be ready before the command starts because the command may be\ngetting its input from someplace other than the keyboard and may be sending it\nsomewhere other than the screen. The figure below shows how the evaluation\nlooks graphically.\n<\/p>\n<p>\n<div align=\"center\">\n<img decoding=\"async\" src=\"cmdflow.png\" width=106 height=380 border=0 usemap=#cmdflow_map>\n<\/div>\n<map name=cmdflow_map>\n<area shape=\"RECT\" coords=\"3,0,104,42\" href=\"popup#splitting the command line into tokens#Here the shell splits the input command into more easily processed chunks (i.e. tokens).\">\n<area shape=\"RECT\" coords=\"2,64,105,113\" href=\"popup#Expand aliases#Here the shell will expand aliases for both command and any other values.\">\n<area shape=\"RECT\" coords=\"1,131,103,175\" href=\"popup#Variable substitution#If the command line contains any variables ($), they are expanded here.\">\n<area shape=\"RECT\" coords=\"2,197,101,237\" href=\"popup#Wildcard expansion#If the command line contains any metacharacters (wildcards), they are evaluated at this step.\">\n<area shape=\"RECT\" coords=\"0,263,101,302\" href=\"popup#Set-up redirection#If you have any redirection, the file descriptors for stdin, stdout and stderr are changed accordingly.\">\n<area shape=\"RECT\" coords=\"1,326,102,369\" href=\"popup#Run the command#Finally the shell tries to run the command.\">\n<\/map>\n<p>\n<icaption>Image &#8211; Steps in interpreting command line input. (<b>interactive<\/b>)<\/icaption>\n<p>\nThis is an oversimplification. Things happen in this order, though many more\nthings occur in and around the steps than I have listed here. What I am\nattempting to describe is the general process that occurs when the <glossary>shell<\/glossary>\nis trying to interpret your command.\n<\/p>\n<p>\nOnce the <glossary>shell<\/glossary> has determined what each command is and each command is an\nexecutable <i>binary<\/i> program (not a <glossary>shell script<\/glossary>), the shell makes a copy of\nitself using the fork() <glossary>system call<\/glossary>.\nThis copy is a <glossary>child process<\/glossary>\nof the <glossary>shell<\/glossary>.\nThe <i>copy<\/i> then uses the exec() <glossary>system call<\/glossary>\nto overwrite itself with the <glossary>binary<\/glossary>\nit wants to execute. Keep in mind that even though the <glossary>child process<\/glossary>\nis executing, the original <glossary>shell<\/glossary> is still in memory, waiting for the child to complete (assuming\nthe command was not started in the background with &amp;).\n<\/p>\n<p>\nIf the program that needs to be executed is a shell script, the program that is created with fork() and exec() is another <glossary>shell<\/glossary>.\nThis new shell starts reading the <glossary>shell script<\/glossary> and interprets it, one line at a time. This is why a\nsyntax error in a <glossary>shell script<\/glossary> is not discovered when the script is started, but\nrather when the erroneous line is first encountered.\n<\/p>\n<p>\nUnderstanding that a new process is created when you run a shell script\nhelps to explain a very common misconception under <glossary>UNIX<\/glossary>.\nWhen you run a shell script and that script changes directories, your original <glossary>shell<\/glossary>\nknows nothing about the change. This confuses a lot of people who are new to <glossary>UNIX<\/glossary>\nas they come from the <glossary>DOS<\/glossary> world, where changing the directory from within a batch\nfile <em>does<\/em> change the original <glossary>shell<\/glossary>.\nThis is because <glossary>DOS<\/glossary> does not have\nthe same concept of a process as <glossary>UNIX<\/glossary> does.\n<\/p>\n<question id=\"455\" text=\"Like DOS, variables changed in Linux shell-scripts are always valid for the shell that started the script.\" \/>\n<question id=\"50\" text=\"Changes to variables by a child process are not seen by the parent.\" \/>\n<concept id=\"97\" description=\"Changes made to variables by a child process are not seen by the parent.\" \/>\n<p>\nLook at it this way: The sub-shell&#8217;s <glossary>environment<\/glossary>\nhas been changed because the current directory is different. However, this\nis <em>not<\/em> passed back to the\nparent. Like &#8220;real&#8221; parent-child relationships, only the children can inherit\ncharacteristics from their parent, not the other way around. Therefore, any\nchanges to the <glossary>environment<\/glossary>,  including directory changes,\nare not noticed by the parent. Again, this is <i>different<\/i> from the behavior\nof <glossary>DOS<\/glossary> .bat  files.\n<\/p>\n<p>\nYou can get around this by either using aliases or <glossary>shell<\/glossary>\nfunctions (assuming that your <glossary>shell<\/glossary>\nhas them). Another way is to use the dot command in front of the\nshell script you want to execute. For example:<\/p>\n<p>\n<commandexample command=\"bash\">. myscript<\/commandexample> &lt;&#8211;NOTICE THE DOT!\n<\/p>\n<p>\nThis script will be interpreted directly by the current <glossary>shell<\/glossary>,\n<i>without<\/i> forking a <glossary>sub-shell<\/glossary>.\n If the script makes changes to the\nenvironment, it is <i>this<\/i> shell&#8217;s <glossary>environment<\/glossary>\nthat is changed.\n<\/p>\n<p>\nYou can use this same functionality\nif you ever need to reset your <glossary>environment<\/glossary>.\nNormally, your <glossary>environment<\/glossary>\nis defined by the start-up files in your home\ndirectory. On occasion, things get a little confused (maybe a <glossary>variable<\/glossary>\nis changed or removed) and you need to reset things. You can you the dot command to do so.\nFor example, with either sh or ksh, you can write it like this:\n<\/p>\n<question id=\"51\" text=\"Preceeding a shell script with a dot when you execute it does what?\" \/>\n<p>\n<commandexample command=\"bash\">. $HOME\/.profile<\/commandexample> &lt;&#8211;NOTICE THE DOT!\n<\/p>\n <question id=\"457\" text=\"After making changes to you .profile, what command would you issue to activate the changes in your current shell?\" \/>\n<p>\nOr, using a function of bash you can also write\n<\/p>\n<p>\n<commandexample command=\"bash\">. ~\/.profile<\/commandexample> &lt;&#8211;NOTICE THE DOT!\n<\/p>\n<question id=\"\" type=\"mc\" text=\"What symbol is used by many shells as a shortcut to a particular users home\ndirectory?\" \/>\n<concept id=\"\" description=\"The tilde (~) is often used as a shortcut to refer to a particular users home\ndirectory\" \/>\n<p>\nThis uses the tilde (~), which I haven&#8217;t mentioned yet. Under many shells,\nyou can use the tilde as a shortcut to refer to a particular users home\ndirectory. For example, if I had a program in my personal <directory>bin<\/directory> ,\nI could start it like this:\n<\/p>\n<p>\n<\/p>\n<commandexample command=\"bash\">~jimmo\/bin\/mycommand<\/commandexample>\n<\/p>\n<p>\nNote that if I am already logged in as the user jimmo, I do not need to specify my\nown username. Instead, I could have run the command like this:\n<\/p>\n<\/p>\n<commandexample command=\"bash\">~\/bin\/mycommand<\/commandexample>\n<\/p>\n<p>\nSome shells keep track of your <em>last<\/em> directory in the OLDPWD\nenvironment <glossary>variable<\/glossary>.\n Whenever you change directories, the system saves your\ncurrent directory in OLDPWD <em>before<\/em> it changes you to the new location.\n<\/p>\n<p>\nYou can use this by simply entering cd $OLDPWD. Because the <glossary>variable<\/glossary>\n$OLDPWD\nis expanded before the cd command is executed, you end up back in your previous\ndirectory. Although this has more characters than just popd, it&#8217;s easier because\nthe system keeps track of my position, current and previous, for you. Also,\nbecause it&#8217;s a <glossary>variable<\/glossary>,\nI can access it in the same way that I can access other environment variables.\n<\/p>\n<p>\nFor example, if there were a file in your old directory that you wanted to\nmove to your current one, you could do this by entering:\n<\/p>\n<p>\n<commandexample command=\"cp\">cp $OLDPWD\/&lt;file_name&gt; .\/<\/commandexample>\n<\/p>\n<question id=\"52\" text=\"The command \"cd -\" does what?\" \/>\n<question id=\"456\" text=\"What command would you use to change to your previous directory?\" \/>\n<p>\nHowever, things are not as difficult as they seem. Typing in\n<i>cd $OLDPWD<\/i> is still a bit cumbersome. It is a lot\nless characters to type in popd -like in the csh. Why isn&#8217;t there something like\nthat in the ksh or bash? There is. In fact, it&#8217;s much simpler. When I first found out about it,\nthe adjective that first came to mind was &#8220;sweet.&#8221; To change directories to your\nprevious directory, simply type  &#8220;cd -&#8220;.\n<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Interpreting the Command When you input a command-line, the shell needs to be able intepret it correctly in order to know what exactly to do. Maybe you have multiple options or redirect the output to a file. In any event &hellip; <a href=\"http:\/\/www.linux-tutorial.info\/?page_id=187\">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-187","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/187","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=187"}],"version-history":[{"count":1,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/187\/revisions"}],"predecessor-version":[{"id":589,"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=\/wp\/v2\/pages\/187\/revisions\/589"}],"wp:attachment":[{"href":"http:\/\/www.linux-tutorial.info\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}