Instance parsing shell sub-process (subshell)

Source: Internet
Author: User

The instance parses shell sub-process (subshell) through an instance to understand the shell sub-process. It mainly includes the following aspects: 1. What is shell Sub-process 2: under what circumstances does shell generate sub-process 3: sub-process features and precautions 4: $ variable $ meaning in the script, and how to get the process number in the sub-process Reference documents: apue, bash man and info documentation 1: What is a shell sub-process, is based on the concept of a parent-child process, the process of the unix operating system starts from the init process (the init process is 1, and the process number 0 is the original process of the system. The process discussed below does not include process 0 in principle) each has its own child process. Even the orphan process resulting from the parent process first ends, it will be adopted by init to set its parent process ID to 1. Because all processes have parent processes, in fact, the creation of all processes can be considered as a sub-process creation process. In apue, we mentioned the creation of unix operating system processes. In general, fork + exec systems are called. To understand how to create and execute a sub-process, you must take at least two steps, including creating a sub-process environment through fork, loading and executing Process Code through exec. For details such as inherited environment variables, see Chapter 8 related chapters of apue. The shell sub-process (subshell), as the name suggests, is a sub-process 2 created by the "Current shell Process: under what circumstances does shell generate the following sub-processes. (The following is an English Excerpt from info bash) 1: &, submit a background job If a command is terminated by the control operator '&', the shell executes the command asynchronously in a subshell.2: pipe Each command in a pipeline is executed in its own subshell3: bracket command list () operator Placing a list of commands between parentheses causes a subshell environment to be created4: Execute external scripts, programs: when Bash finds such a file while searching the '$ path' for a command, it spawns A subshell to execute it. In other words, executing filename ARGUMENTS is equivalent to executing bash filename ARGUMENTS Description: Generally, the creation of sub-processes includes the above four situations. It should be noted that as long as it meets one of the above four situations, a (fork) sub-process will be created, regardless of whether it is a function, command, or program, it's not because it's a built-in function (buitin) or an external program. In addition, the two steps of sub-process creation and execution are mentioned above. The creation of shell Sub-process is not much different in one step. Generally, the parent process calls fork to generate the process environment, it is estimated that there is a difference in step 2 exec. As an interpreted language program, shell is provided to the program body loaded and executed by Step 2 exec instead of the script itself, but by the first line #! By default, it is a shell program. Of course, it can also be awk, sed, and other programs. In a previous article, we mentioned how the set id of the shell script takes effect. We will not discuss it here. However, the execution of sub-processes varies depending on the situation. For built-in functions, the exec program is a shell program, and the built-in function is called directly in the sub-shell, while external functions or programs, after the sub-process environment is created, there are roughly two types of execution: 1: Direct exec external program, such as the sleep and pstree commands directly executed in the following example. 2: the subshellexec program is a shell program, on which a sub-process is created to execute the function. For example, in the following example, the shell command in the background program is submitted through the function. For example, the built-in function (directly executed in subshell, whether or not the function is used) [root @ localhost shell] # mkfifo a [root @ localhost shell] # type echoecho is a shell builtin [root @ localhost shell] # B () {echo a> ;} [root @ localhost shell] # B & [1] 15697 [root @ localhost shell] # echo a> a & [2] 15732 [root @ localhost shell] # pstree-pa $ $ bash, 571 |-bash, 15697 |-bash, 15732 '-pstree, 15734-pa 571 example: Define the function and submit it to the background (sleep in function call creates another one under subshell Sub-processes, while pstree and sleep commands are directly executed on sub-processes.) [root @ localhost shell] # a () {sleep 30 ;}; [root @ localhost shell] # sleep 40 & [1] 15649 [root @ localhost shell] # a & [2] 15650 [root @ localhost shell] # pstree-pa $ bash, 571 |-bash, 15650 | '-sleep, 15651 30 |-pstree, 15652-pa 571'-sleep, 15649 40 for the fourth point, pay attention to the shell script execution mode, in the second mode of the fourth point, the shell will create a sub-process: filename ARGUMENTSbash filename ARGUMENTS. However, the shell also provides two methods for creating a process without a sub-program: 1: sour. Ce command, use method Source filename ARGUMENTS or. filename ARGUMENTS: This method directly executes the filename script in the current shell process. After filename ends, it continues to return the current shell process 2: exec command, exec filename ARGUMENTS: Execute the filname script directly in the current shell process. Exit the current shell process after filename ends. 3. The features and precautions of the sub-process are not described in detail, only one error is prompted when writing a script. As a sub-process, the process environment is independent from the parent process environment. Therefore, During Variable transfer, you must note that the sub-process cannot change the variables to the parent process. For example, in the following example, the sum value is summed and assigned to the external variable sum, and the result sum value does not change as a result: [root @ localhost shell] # sum = 0 [root @ localhost shell] # echo '1 2 3 4 '| sed's // n/G' | while read line; do sum + = $ line; done [root @ localhost shell] # echo $ sum0 [root @ localhost shell] #4: variable $ meaning variable in the script $ represents the progress and id of the Current shell Process. Pay special attention to the "current shell" here ", let's take a look at the description '$' Expands to the process ID of the shell in info bash. in A' () 'subshell, it expands to the process ID of the invoking shell, Not the subshell. let's take a look at the description in man bash $ Expands to the process ID of the shell. in a () subshell, it expands to the process ID of the current shell, not the subshell. therefore, in the actual environment, $ is not necessarily the process Number of the current process, but the process Number of the Current shell Process. From this document, you should note the relationship between invoking shell (info) or current shell (man) and the current subshell process. This leads to several questions. 1: What is current shell2: which current shell3 corresponds to $ in a child process: how to obtain the child process $? For debugging and testing, the following example references several variables: BASH_SOURCE 'an array variable whose members are the source filenames corresponding to the elements in the 'funcname' array variable. 'bash _ lineno' An array variable whose members are the line numbers in source files corresponding to each member of FUNCNAME. '$ {BASH_LINENO [$ I]}' is the line number in the source file where '$ {FUNCNAME [$ I]}' was called. the corresponding source f Ile name is '$ {BASH_SOURCE [$ I]}'. use 'lineno' to obtain the current line number. 'funcname' An array variable containing the names of all shell functions currently in the execution call stack. the element with index 0 is the name of any currently-executing shell function. the bottom-most element is "main ". this variable exists only when a shell function is executing. assignments to 'funcname' have No effect and return an error status. if 'funcname' is unset, it loses its special properties, even if it is subsequently reset. set-x in the script, and set the PS4 Tracking Program Execution Process PS4 = '+ [$ SHELL] [$ BASH_SUBSHELL] [$ PPID-$] [$ LINENO] ["$ {BASH_SOURCE [*]}"] [$ {FUNCNAME [*]}] [$ {BASH_LINENO [*]}]/n + PS4 set the display value as follows: [$ SHELL]: current shell path [$ BASH_SUBSHELL]: Sub-shell path length [$ PPID-$]: parent process id, and variable $ value (current shell process ID) [$ LINENO]: the command line number in the current shell ["$ {BASH_SOURC E [*]} "]: source script program file record queue [$ {FUNCNAME [*]}]: function call record queue [$ {BASH_LINENO [*]}]: run the line number record queue program as follows: [root @ localhost shell] # cat-n subshell. sh + [/bin/bash] [0] [569-571] [1060] [""] [] [] + cat-n subshell. sh 1 #! /Bin/bash 2 3 set-x 4 sub2 () {5 # sh subshell2.sh 6 sleep 1 7} 8 sub () {9 sub2 & 10 sleep 20 11} 12 sub & 13 pstree-p $ PPID: [root @ localhost shell] # bash subshell. sh + [/bin/bash] [0] [569-571] [1059] [""] [] [] + bash subshell. sh + [/bin/bash] [0] [571-17858] [12] ["subshell. sh "] [] [0] + sub + [/bin/bash] [0] [571-17858] [13] [" subshell. sh "] [] [0] + pstree-p 571 + [/bin/bash] [1] [571-17858] [10] [" subshell. sh sub Shell. sh "] [sub main] [12 0] + sleep 20 + [/bin/bash] [1] [571-17858] [9] [" subshell. sh subshell. sh "] [sub main] [12 0] + sub2 + [/bin/bash] [2] [571-17858] [6] [" subshell. sh subshell. sh subshell. sh "] [sub2 sub main] [9 12 0] + sleep 1 bash (571) --- bash (17858)-+-bash (17859)-+-bash (17860) --- sleep (17863) | '-sleep (17862)'-pstree (17861) Description: 1: first, run subshell under the current shell (process id 571. sh to generate sub-processes. [$ PPID-$] = [571-17858] indicates that subshell is executed. sh The script's process number is 17858. [] [0] indicates that no function call is performed. If no function record is generated, it is found in subshell. in the sh execution process, the $ value saved "current shell" is itself, and 17858 [$ LINENO] = [12] is displayed in subshell. sh Line 12th calls the sub function and calls it in the program through the & submit background method. The process tree shows that the sub function is called after the 17858 process and the sub process 17859 is created, when the execution body is bash, ppid indicates that the parent process is 571 and the $ variable value is 17858. This indicates that the "current shell" of the sub-generated process is still subshell. sh Script Execution Process 17858 [$ LINENO] = [13] is displayed in subshell. sh Line 13th executes the pstree command to call the process tree directly in the script. The pstree command directly creates the sub-process 17858 after the 17861 process and runs it, ppid indicates that the parent process is 571, $ variable value The value is 17858, indicating that the "current shell" of the sub-process running the pstree command is still subshell. sh Script Execution Process 17858 2: [sub main] [12 0] display into sub function [$ LINENO] = [9] display execution (within sub function) script 9th lines, the sub2 function process tree shows that after the sub2 function is called, the sub-process 17859 is created and the execution body is bash. At this time, ppid still indicates that the parent process is 17860, $ the value of the variable is 17858, indicating that the "current shell" of the sub2 call is still subshell. sh Script Execution Process 17858 [$ LINENO] = [10] displays the execution (within the sub function) script 10th lines, sleep command: The sleep command is called directly in the sub function in the script to call the process tree, the sleep command is the process 17859 created when the sub function is called, and then the sub-process 17862 is created and executed. At this time, the ppid indicates that the parent The variable value is 571 and $ is 17858, indicating that the "current shell" of the child process running the pstree command is still subshell. sh Script Execution Process 17858 3: [sub2 sub main] [9 12 0] display into sub2 function [6] display execution (within sub2 function) script 6th lines, sleep 1 here the sleep command is called directly in the sub2 function in the script, the sleep command is the process 17860 created when the sub2 function is called, and then the sub-process 17863 is created and executed. The ppid indicates that the parent process is 571, and the $ variable value is 17858, it indicates that the "current shell" of the sub-process running the sleep command is still subshell. sh Script Execution Process 17858 has only two values, one is the initial bash shell: 571 and the other is subshell. the process generated when the sh script is called: 17858 other processes are called by subshell. sh Sub-process, whether it is a function or command run, $ the "current shell" stored in the variable value is subshell. sh process generated during the call: 17858 the above four Seed shell creation methods are inferred: Submit the background, pipeline, bracket command list, and script call. It seems that only the fourth method-script call-can generate the subshell which can be "current shell". The following two examples can be used to demonstrate this inference again. Example 1: change the script call method, this method uses the Current shell Process to execute subshell. sh, do not create a sub-process result $ the "current shell" stored in the variable value is the current process [root @ localhost shell] # source subshell. sh + [/bin/bash] [0] [569-571] [1062] [""] [] [] + source subshell. sh ++ [/bin/bash] [0] [569-571] [3] ["subshell. sh "] [] [1062] + set-x ++ [/bin/bash] [0] [569-571] [13] [" subshell. sh "] [] [1062] + pstree-p 569 + [/bin/bash] [0] [569-571] [12] ["subshell. sh "] [] [1062] + sub ++ [/bin/bash] [1] [569-571] [1] [" subshell. sh subshell. sh "] [sub source] [12 1062] + sub2 ++ [/bin/bash] [2] [569-571] [2] [" subshell. sh subshell. sh subshell. sh "] [sub2 sub source] [1 12 1062] sleep 1 ++ [/bin/bash] [1] [569-571] [2] [" subshell. sh subshell. sh "] [sub source] [12 1062] + sleep 20 sshd (569) --- bash (571)-+-bash (18801) --- sleep (18804) |-bash (18806) --- bash (18808) --- sleep (18809) '-p Example 2 of stree (18807): In a sub-process, add the subshell2.sh script to the subprocess by using the script call method or by using the sub-process ID, and run the following command in subshell. sh to call + cat-n subshell2.sh 1 #! /Bin/bash 2 set-x 3 echo $ PPID 4 sleep 10 + cat-n subshell. sh 1 #! /Bin/bash 2 3 set-x 4 sub2 () {5. /subshell2.sh & 6 sleep 1 7} 8 sub () {9 sub2 & 10 sleep 20 11} 12 sub & 13 pstree-pa $ PPID [root @ localhost shell] #. /subshell. sh + [/bin/bash] [0] [569-571] [1138] [""] [] [] +. /subshell. sh + [/bin/bash] [0] [571-19715] [13] [". /subshell. sh "] [] [0] + pstree-pa 571 + [/bin/bash] [0] [571-19715] [12] [". /subshell. sh "] [] [0] + sub + [/bin/bash] [1] [571-19715] [9] [". /subshell. sh. /subshell. Sh "] [sub main] [12 0] + sub2 + [/bin/bash] [2] [571-19715] [5] [". /subshell. sh. /subshell. sh. /subshell. sh "] [sub2 sub main] [9 12 0]. /subshell2.sh + [/bin/bash] [2] [571-19715] [6] [". /subshell. sh. /subshell. sh. /subshell. sh "] [sub2 sub main] [9 12 0] sleep 1 + [/bin/bash] [1] [571-19715] [10] [". /subshell. sh. /subshell. sh "] [sub main] [12 0] + sleep 20 + [/bin/bash] [0] [19718-19719] [3] [". /subshell2.sh "] [] [0] + echo 197181971 8 + [/bin/bash] [0] [19718-19719] [4] [". /subshell2.sh "] [] [0] + sleep 10 bash, 100'-subshell. sh, 19715. /subshell. sh |-pstree, 19717-pa 571 '-subshell. sh, 19716. /subshell. sh |-sleep, 19721 20'-subshell. sh, 19718. /subshell. sh |-sleep, 19720 1'-subshell2.sh, 19719. /subshell2.sh '-sleep, 19722 10 from the execution result above, we can see that when the program runs into subshell2.sh, the process environment with process number 19294 is created, $ the "current shell" stored in the variable value is the process created when it is updated to subshell2.sh: in this way, the created subshell 2. The parent process id of sh is actually the process created when sub2 is called. In this way, some subprocess IDs that cannot be displayed by $ are displayed.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.