Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
scripting:processtree [2010/04/21 21:14]
127.0.0.1 external edit
scripting:processtree [2017/06/13 06:16] (current)
mtmr type from importss -> imports
Line 5: Line 5:
 ===== The process tree ===== ===== The process tree =====
  
-The processes in UNIX(r) are - unlike ​in other systems ​you may have seen - **organized ​in a tree**. Every process has a parent process that started ​it or is responsible for it. Also, every process has an own **context memory** (I don't mean the memory where the process stores its data, I mean memory where data is stored that doesn'​t directly belong to the process, but is needed to run the process)__**The environment**__.+The processes in UNIX(r) are - unlike other systems - **organized ​as a tree**. Every process has a parent process that startedor is responsiblefor it. Every process has its own **context memory** (Not the memory where the process stores its data, rather, the memory where data is stored that doesn'​t directly belong to the process, but is needed to run the process) ​i.e. __**The environment**__.
  
-To make it really clear I want to repeat it: Every process has its **own** environment space.+Every process has its **own** environment space.
  
-The environment stores, ​beside ​other stuff, data that's useful ​for usThe **environment variables**. These are strings in the common ''​NAME=VALUE''​ form, but they are not related to shell variables. A variable named ''​LANG'',​ for example, is used by every program that looks it up in its environment to determinate the current locale.+The environment stores, ​among other things, data that's useful ​to usThe **environment variables**. These are strings in common ''​NAME=VALUE''​ form, but they are not related to shell variables. A variable named ''​LANG'',​ for example, is used by every program that looks it up in its environment to determinate the current locale.
  
-**__Attention:​__** A variable that is set, like with ''​MYVAR=Hello'',​ is **not** automatically part of the environment. You need to put it into the environment with the ''​export'' ​utility:+**__Attention:​__** A variable that is set, like with ''​MYVAR=Hello'',​ is **not** automatically part of the environment. You need to put it into the environment with the bash builtin command ​''​export'':​
 <​code>​export MYVAR</​code>​ <​code>​export MYVAR</​code>​
-Common system variables like ''​PATH'' ​or ''​HOME''​ usually already ​are part of the environment (as set by login scripts or programs).+Common system variables like [[syntax:​shellvars#​PATH|PATH]] ​or [[syntax:​shellvars#​HOME|HOME]] ​are usually ​part of the environment (as set by login scripts or programs).
  
 ===== Executing programs ===== ===== Executing programs =====
  
-All the diagrams of the process tree use names like "''​xterm''"​ or "''​bash''",​ but that's just for you to understand what's going on, it doesn'​t mean it really runs processes ​with these names.+All the diagrams of the process tree use names like "''​xterm''"​ or "''​bash''",​ but that's just to make it easier ​understand what's going on, it doesn'​t mean those processes ​are actually executed.
  
-Let's take a short look what happens when you "​execute a program"​ from the Bash prompt, a program like "​ls":​+Let's take a short look at what happens when you "​execute a program"​ from the Bash prompt, a program like "​ls":​
  
 <​code>​ <​code>​
Line 34: Line 34:
 xterm ----- bash ----- bash(copy) xterm ----- bash ----- bash(copy)
 </​code>​ </​code>​
-...and after the "​second Bash" (the copy) replaced ​itself ​by the ''​ls''​-program (it execs it), it might look like+...and after the "​second Bash" (the copy) replaces ​itself ​with the ''​ls''​ program (the copy execs it), it might look like
 <​code>​ <​code>​
 xterm ----- bash ----- ls xterm ----- bash ----- ls
 </​code>​ </​code>​
  
-If everything was okay, the two steps resulted in one program being ran. The copy of the environment from the first step (forking) ​results in the environment for the final running program (''​ls'' ​in this case).+If everything was okay, the two steps resulted in one program being run. The copy of the environment from the first step (forking) ​becomes ​the environment for the final running program (in this case, ''​ls''​).
  
-__**What is so important about it?​**__ ​Well, in our example, ​whatever ​the program ''​ls'' ​will do inside its own environment,​ it can'​t ​have any effect to the environment of its parent process (''​bash'' ​here). The environment was copied when ls was executed. ​**That'​s a one-way!** ​Nothing ​will "copy it back" when ''​ls''​ terminates!+__**What is so important about it?​**__ ​In our example, ​what the program ''​ls'' ​does inside its own environment,​ it can'​t ​affect ​the environment of its parent process (in this case, ''​bash''​). The environment was copied when ls was executed. Nothing ​is "copied ​back" ​to the parent environment ​when ''​ls''​ terminates.
  
 ===== Bash playing with pipes ===== ===== Bash playing with pipes =====
  
-Pipes are a very powerful tool. You can connect the out- and inputstreams ​of two separate programs, and thus create a new utility - or better: a new functionalityWell, we're not here to explain piping, we just want to see how they look in the process tree. Again, we execute some commands ​''​ls''​ and ''​grep'':​+Pipes are a very powerful tool. You can connect the output ​of one process to the input of another processWe won't delve into pipign at this point, we just want to see how it looks in the process tree. Again, we execute some commands, this time, we'll run ''​ls''​ and ''​grep'':​
  
 <​code>​ <​code>​
Line 58: Line 58:
 </​code>​ </​code>​
  
-Just to be boring ​again''​ls''​ can't influence the environment of ''​grep''​''​grep''​ can't influence the environment of ''​ls'',​ neither ''​grep''​ nor ''​ls''​ can influence the environment of ''​bash''​.+Note once again''​ls''​ can't influence the ''​grep'' ​environment. ​''​grep''​ can't influence the ''​ls'' ​environmetand neither ''​grep''​ nor ''​ls''​ can influence the ''​bash'' ​environment.
  
 __**How is that related to shell programming?​!?​**__ __**How is that related to shell programming?​!?​**__
  
-Well, imagine some Bash-code that reads data from a pipe. Let's take the internal command ''​read'',​ which reads data from //stdin// and puts it into a variable. We run it in a loop here - we count input lines...:+Well, imagine some Bash code that reads data from a pipe. For example, ​the internal command ''​read'',​ which reads data from //stdin// and puts it into a variable. We run it in a loop here to count input lines:
  
 <​code>​ <​code>​
 counter=0 counter=0
-cat /etc/passwd | while read LINE; do ((counter++));​ done + 
-echo Lines: $counter+cat /etc/passwd | while read; do ((counter++));​ done 
 +echo "Lines: $counter"
 </​code>​ </​code>​
  
 What? It's 0? Yes! The number of lines might not be 0, but the variable ''​$counter''​ still is 0. Why? What? It's 0? Yes! The number of lines might not be 0, but the variable ''​$counter''​ still is 0. Why?
-Remember the diagram from above? ​I'll rewrite ​it a bit:+Remember the diagram from above? ​Rewriting ​it a bit, we have:
 <​code>​ <​code>​
                    +-- cat /etc/passwd                    +-- cat /etc/passwd
 xterm ----- bash --| xterm ----- bash --|
-                   +-- bash (while read LINE; do ((counter++));​ done)+                   +-- bash (while read; do ((counter++));​ done)
 </​code>​ </​code>​
  
-See the relation? The forked Bash will count the lines like a charm. It will also set the variable ''​counter'' ​like you wanted it. But if everything ends, this extra process will be terminated - **your variable is gone** ​- R.I.P. ​You see a 0 because in the main shell it always ​was 0 and never something else!+See the relationship? The forked Bash process ​will count the lines like a charm. It will also set the variable ''​counter'' ​as directed. But if everything ends, this extra process will be terminated - **your ​"​counter" ​variable is gone** You see a 0 because in the main shell it was 0and wasn't changed by the child process!
  
-__**Aha! And now, how to count those lines?​**__ +__**So, how do we count the lines?​**__ 
-Easy: **Avoid the subshell.** ​How you do it in detail doesn't matter, the important thing is that the shell that sets the counter must be the "main shell"​. For example ​do it like this:+Easy: **Avoid the subshell.** ​The details don't matter, the important thing is the shell that sets the counter must be the "main shell"​. For example:
  
 <​code>​ <​code>​
 counter=0 counter=0
-while read LINE; do ((counter++));​ done </​etc/​passwd + 
-echo Lines: $counter+while read; do ((counter++));​ done </​etc/​passwd 
 +echo "Lines: $counter"
 </​code>​ </​code>​
  
-It's nearly self-explaining. The ''​while''​-loop runs in the **current shell**, the counter is increased ​in the **current shell**, everything vital happens in the **current shell**, also the ''​read''​-command sets the variable ''​LINE'',​ though we don't use it here, it's just a dummy. This small script should work.+It's nearly self-explanitory. The ''​while''​ loop runs in the **current shell**, the counter is incremented ​in the **current shell**, everything vital happens in the **current shell**, also the ''​read''​ command sets the variable ''​REPLY'' ​(the default if nothing is given), though we don't use it here.
  
 ===== Actions that create a subshell ===== ===== Actions that create a subshell =====
Line 99: Line 101:
 As shown above, Bash will create subprocesses everytime it executes commands. That's nothing new. As shown above, Bash will create subprocesses everytime it executes commands. That's nothing new.
  
-But imagine ​your command ​actually ​is a script ​that sets variables you want to use in your main script. This won't work.+But if your command is a subprocess ​that sets variables you want to use in your main script, that won't work.
  
-For exactly this purpose, there'​s the ''​source''​ command (also: the //dot// ''​.''​ command). ​It doesn'​t ​really actually ​execute the script ​like it would execute any other program - it's more like including ​the other script'​s ​source ​code into the current shell:+For exactly this purpose, there'​s the ''​source''​ command (also: the //dot// ''​.''​ command). ​Source ​doesn'​t execute the scriptit imports ​the other script'​s code into the current shell:
 <​code>​ <​code>​
 source ./​myvariables.sh source ./​myvariables.sh
Line 110: Line 112:
 ==== Pipes ==== ==== Pipes ====
  
-The last big section was about pipes, so no example here...+The last big section was about pipes, so no example here.
 ==== Explicit subshell ==== ==== Explicit subshell ====
  
Line 117: Line 119:
 ==== Command substitution ==== ==== Command substitution ====
  
-With [[syntax:​expansion:​cmdsubst | command substitution]] you re-use the output of another command as text in your commandline, for example to set a variable. ​This other command is run in a subshell: +With [[syntax:​expansion:​cmdsubst | command substitution]] you re-use the output of another command as text in your command line, for example to set a variable. ​The other command is run in a subshell: 
-<​code>​NUMBER_OF_USERS=$(cat /etc/passwd | wc -l)</​code>​ +<​code>​number_of_users=$(cat /etc/passwd | wc -l)</​code>​ 
-Note that, in this example, ​you create ​a second subshell by using a pipe in the command substitution ​(just as sidenote):+Note that, in this example, ​ a second subshell ​was created ​by using a pipe in the command substitution:​
 <​code>​ <​code>​
                                             +-- cat /etc/passwd                                             +-- cat /etc/passwd
  • scripting/processtree.1271884448.txt
  • Last modified: 2010/12/20 03:00
  • (external edit)