[Linux] Understanding of Linux environment variables --- command line parameters, shell subprocesses, environment, local variables...

Come on Bruce, you can do it!
insert image description here

Article Directory



1. The system default search path in the environment variable PATH

1. Install the program to the /usr/bin directory (without ./ to run the program written by yourself)

1.
The Linux instructions we usually use are actually executable programs, which are no different from the binary programs we write ourselves, so why do we need to add ./ when executing our own programs, and execute the instructions provided by these systems (executable program ), do not need to add ./?

insert image description here

2.
To execute a program or command, you must first find the program.
This is why we need to add ./ (current path) when executing the program we wrote. This is actually to find the program we wrote, and the system command is actually the default location of the system to help us find the program and Execution, if you want to execute your own program without ./, you need to install the program (the essence of installation is to copy) to the /usr/bin directory, which is the path of the system installation command .

But it is not recommended to install your own program in the default path of the system, because your program has not been strictly tested and will pollute the instruction pool of the system, so if you install it,It is recommended to delete it after playing!
insert image description here

2. Add the program path to the PATH environment variable (without ./ to run the program written by yourself)

1.
Why can the system find the programs under the /usr/bin path? In fact, it is because there is an environment variable PATH in the system. When the operating system starts, it will define a PATH variable in the context of the shell. This variable is globally valid. If you want to view the content, you can use the echo command and set it in front of PATH. Add the $ sign.

2.
When executing system commands, the system will default to the path in the PATH environment variable to search for the command program we input. If found, the system will execute the program. If not found, it will report an error command not found, so if you want to Another way to execute your own program without ./ is to add the path of your own program to the environment variable PATH.
We can modify the value of PATH arbitrarily, because as long as we log out again, the PATH environment variable will be restored again

insert image description here
3.
export can be used to import shell variables into the environment variable PATH. When importing, you need to import the old environment variables first and then add a new path, otherwise your path will directly overwrite the previous environment variable PATH. In the case of all paths, all programs under the paths in PATH are defaulted to be system commands

insert image description here

insert image description here

4.
The which command is actually searched from the path under the environment variable PATH in the underlying implementation to help us find the corresponding command path. If the path where our program is located is also added to the PATH, then which can also find us written program.

insert image description here

5.
Our environment variables are memory-level, so after you import your own path to the environment variable PATH, it is only temporary. After you exit xshell, your environment variables will return to the default state

2. In-depth understanding of environmental variables

1. The relationship between the shell process and environment variables

1.
When we log in to the shell, it will default your current shell process to execute the contents of the corresponding bash_profile once, which is to import the environment variables into your current shell process, and the configuration of the environment variables is started through it When loaded into bash, linux has environment variable settings in the environment variable configuration file. When we log in to the shell, this environment variable will be loaded into the current shell process.

2.
As a special interactive tool with the Linux system, the shell provides users with ways to start programs, manage files in the file system, and processes running on Linux. The shell achieves the function of interacting with the system by parsing the input text commands and executing them in the kernel. The shell includes a set of internal commands through which operations such as file management, program management, and operation can be performed.

3.
In addition to executing through the command line on the text command interface (or virtual controller terminal or terminal emulator), it can be executed as a program by putting multiple shell commands into files, and these files are shell scripts. There are many different types of shells (such as ash, tsch, zsh, etc.) in the Linux system. They each have different characteristics, and you can choose according to your needs. Usually the default shell of a Linux distribution is the bash shell (a Unix-like shell developed by the GNU project).

4.
Usually when we execute the shell command, we intuitively feel that the command is directly run on the Linux system. In fact, this is a subjective misunderstanding. The shell itself is a program that runs on Linux. The execution of the shell command is in running in the corresponding process

5.
When the user logs in to the virtual terminal or terminal emulator, the default shell program will be started. What shell a user starts at login depends on the user's default shell listed in the /etc/passwd user configuration file.

6.
The Linux system itself also has a default shell that is /bin/sh, which is used to start the default shell specified by the system shell script in the system. Usually in the Linux system this file is a symbolic link file, pointing to the /bin/bash shell, you can also change the link of /bin/sh to replace the system default shell

7.
The shell started by the user logging in to the terminal is a parent shell. When a bash command or other equivalent bash command is entered after the prompt of the terminal, a new shell program will be created. This shell is called a subshell. As follows, we enter the bash command twice in the terminal and use ps --forest to view the nesting relationship of the process, we can see the relationship between the parent shell and the sub shell

Part of the shell process in the third part of this article is reproduced from the article of csdn blogger ONLY_MIT

2. The role of environment variables and the preparation of the Linux operating system

1.
Whether it is a program written by ourselves or a program prepared by the operating system in advance, it must be loaded into the memory before running, because the CPU can only read code and data from the memory, but there is a potential The problem is that if these programs want to run, the operating system must first find these programs, and only after finding these programs can they be loaded into the memory.

2. To
find these programs, the operating system must go to a specific path to find these programs, including the command programs that come with the system and programs written by ourselves. The operating system may also find header files, dynamic libraries, static libraries, etc. Wait, but why do you say that if the operating system can find these things, it will definitely find them? How does the operating system find these things?

3.
In fact, if you want to find these things, the operating system needs to do a lot of preparatory work to be as easy as we said. If you want to find something, you can find that thing, so when the operating system starts, it has already By default, it reads from the configuration file which path he has installed the software to, and he records the important information in the configuration file under which path he installed it. When the OS starts, import the information in the configuration file into the In the memory, a memory-level variable is constructed, which is an environment variable. The PATH environment variable mentioned above means that when the operating system starts the command line interpreter shell, it imports variables such as PATH into the context of the shell. When we execute the corresponding command, we must find the corresponding executable program through the default search path specified in the PATH environment variable, so the operating system has actually done a lot of preparatory work for us to find the executable program. Help us define a lot of environment variables, and help us do a lot of work that we can't see through the environment variables. In addition to the PATH environment variable, there are actually many other environment variables. The operating system needs to complete many other things that we ignore. It needs to rely on the environment variables defined by itself. These environment variables have different purposes, such as color schemes, current paths, host names, user names, historical command records, and default shell types. The environment variables defined by the OS itself can implicitly solve or deal with problems and tasks that we cannot see.

insert image description here

4.
In different usage scenarios, the operating system is required to pre-set a batch of variables that may be used by the future shell when explaining the command line after starting the shell, and complete the interpretation of the commands we input through these variables , so in order to meet different application scenarios, the operating system must pre-set a large number of global variables in its own OS. These global variables are actually environment variables!

3. Test the environment variable USER

1.
su - actually let root log in again. At this time, a lot of things will be reloaded as root, and all root-related environment variables will be loaded into the context of the shell. su is just to switch the identity, but the current The path is unchanged.

2.
It can be seen that the environment variable USER will continuously update its variable value as our identity is switched, which is exactly what the USER environment variable can do.

insert image description here

4. Test the environment variable HOME

1.
The HOME environment variable records the specific path where the current user's working directory is.

insert image description here
2. The essence of
cd is actually that when the shell parses the command, when it sees the tilde , the shell will directly call the value of the environment variable HOME

insert image description here

3. The relationship between environment variables and local variables (local variables include environment variables)

1. The shell subprocess will inherit environment variables

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #define USER "USER"
  5 #define MY_ENV "myval"
  6 
  7 
  8 int main()
  9 {
    
    
 10     char*myenv=getenv(MY_ENV);
 11     if(NULL == myenv)
 12     {
    
    
 13         printf("%s: not found\n",MY_ENV);
 14         return 1;
 15     }
 16     printf("%s=%s\n",MY_ENV,myenv);
 17                                                                                                                                                                      
 18     return 0;
 19 }  

1.
The local variables defined by the parent process shell will not be inherited by the child process, but the environment variables of the parent process will be inherited by the child process. The reason for inheritance is to meet different application scenarios, because many system commands (ls, whoami, pwd, which, su - ) all involve the use of environment variables, so these instructions (child processes) must inherit the environment variables of the parent process bash to meet different usage scenarios.
Therefore, environment variables are global, because both the parent process and the child process have environment variables, and the environment variables of the child process are inherited from the parent process.

2. The
local variable will only be valid inside the current process bash, because it will not be inherited and has locality.

insert image description here

2. Instructions to display local variables and environment variables

1.
The set command can display environment variables and non-environment variables in the shell

insert image description here
2.
There are many variables displayed by set, because the shell local variables include environment variables

The following local variable > is the prompt when the command continues
insert image description here
insert image description here

3.env can display all environment variables

insert image description here

3. Import environment variables + cancel local variables

export MYVAL="youcanseeme"
unset MYVAL

1.
To import environment variables, you can first define local variables on the command line, and then import them into environment variables. You can also perform two steps at the same time. You can use the unset command to cancel environment variables or local variables.

insert image description here
2.
Since the environment variables defined by themselves are strings by default, they can be defined with double quotes or without double quotes, but if the defined environment variables have spaces, they must be double quotes , so it is still recommended to bring a space when defining

4. Why does ls display files without ./? (The shell will maintain environment variables)

1.
The shell will maintain the value of the environment variable. For example, if we switch paths continuously, the value of the environment variable PWD will be changed to the current path by the shell at any time, so ls will inherit the value of PWD when running as a child process. After that, ls can display where the current path is as it should be.

2.
Next, we can also use the operation of the C language program to obtain the current path, and use the characteristics of the shell to maintain the environment variable PWD in real time to complete.

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #define USER "USER"
  5 #define MY_ENV "myval"
  6 #define MYPWD "PWD"
  7 
  8 int main()
  9 {
    
    
 10     printf("%s\n",getenv(MYPWD));
 11 }   

5. Detailed discussion on configuration files of environment variables

insert image description here
Reprinted from csdn blogger's sheep eating fish article

4. Command line parameter table and environment variable table

1. Command line parameter list

1.
There are actually hidden parameters in the main function, but we usually don’t use these parameters, because we usually don’t need them. In system programming, using these parameters is relatively common, and main will be called by a function called START_UP Call, the START_UP function is called by the operating system when your program is loaded into the memory. The parameter is actually our command line interpreter bash, which is passed by the parent process. We only need to write instructions on the command line. When the shell interprets our instructions, it will pass parameters to the main function.

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #define USER "USER"
  5 #define MY_ENV "myval"
  6 #define MYPWD "PWD"
  7 #include <unistd.h>
  8 
  9 
 10 
 11 int main(int argc ,char* argv[])
 12 {
    
    
 13 
 14     for(int i=0;i<argc;i++)
 15     {
    
    
 16         printf("argv[%d]->%s\n",i,argv[i]);
 17     }
 18 
 19 }    

2.
When running a program on the command line, you can actually add command line parameters. When the shell interprets these commands, it will pass parameters to the main function

insert image description here
3.
The first parameter in the main function is the number of strings when the program is run on the command line, with spaces as separators, such as -a -b -c when running above, which are actually three strings, ./mycmd is also a string, so argc represents the number of strings, and the pointers in the argv pointer array point to these strings. Through the program running results and code, this conclusion can be proved, and printed out in the argv array The value of is actually these strings, so the second parameter in the main function is the command line parameter table, and the pointers in the table point to all the strings in the command line.

insert image description here

So what's the point of him?

4.
The system command is actually a program written in C language, so when it is run with commands, it can also achieve different functions. How can this be done? In fact, the main function in the implemented code needs parameters such as argc and argv to realize

insert image description here

Next, we will simply implement a process with different options and different functions.

int main(int argc ,char* argv[])
   12 {
    
    
   13 
   14     if(strcmp("-a",argv[1]) == 0)
   15     {
    
    
   16         printf("功能a\n");
   17     }                            
   18      
   19     if(strcmp("-b",argv[1]) == 0)
   20     {
    
    
   21         printf("功能b\n");
   22     }                            
   23     if(strcmp("-c",argv[1]) == 0)
   24     {
    
                         
   25         printf("功能c\n");
   26     }                            
   27      
   28     if(strcmp("-ac",argv[1]) == 0)
   29     {
    
    
   30         printf("功能ac\n");
   31     }                             
   32     if(strcmp("-bc",argv[1]) == 0)
   33     {
    
                          
   34         printf("功能bc\n");                                                                                                                                                          
   35     }                             
   36     if(strcmp("-ab",argv[1]) == 0)
   37     {
    
    
   38         printf("功能ab\n");
   39     }                             
   40     if(strcmp("-abc",argv[1]) == 0)
   41     {
    
                          
   42         printf("功能abc\n");
   43     }                              
   44 }

insert image description here
5. Therefore, the greatest significance of the command line parameters is that the process has different functions through different parameters (that is, the options carried during execution) .

6.
In the command prompt under Windows, we can also use different command line parameters to make the process realize different functions, such as the following shutdown command, you can set the shutdown time, or you can cancel the shutdown, select shutdown, through - t, -a, -s and other parameters to achieve.

insert image description here

2. Three ways to obtain environment variables in the child process

2.1 Obtain environment variables through system calls (obtain the specified environment variable content)

1.
You can get the value of the environment variable USER through the getenv( ) system call

 1 #include <stdio.h>
    2 #include <stdlib.h>
    3 #include <string.h>
    4 #define USER "USER"
    5 
    6 
    7 
    8 int main()
    9 {
    
    
W> 10     char*who = getenv(USER);
   11     printf("USER:%s\n",who);                                                                                                                                       
   12     return 0;                                                                                                               
   13 }

insert image description here

2.
The essence of sudo is actually to change the environment variable USER from ordinary users to root users. At this time, some behaviors that are not allowed to be done by ordinary users can be done by root users.

The following code explains in a popular way the principle of permission denials that we usually encounter when performing certain operations in an ordinary capacity. In fact, in the real process, we need to use getenv() and the system call stat( ), use these system calls to check whether you have the permission for the corresponding operation.

3. Stat obtains file attributes. This system call interface will be explained in detail in the following blog posts.

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <string.h>
  4 #define USER "USER"
  5 
  6 
  7 
  8 int main()
  9 {
    
    
 10     char*who = getenv(USER);
 11     if(strcmp(who,"root")==0)
 12     {
    
    
 13         printf("USER:%s\n",who);
 14 
 15     }
 16     else
 17     {
    
                                                                                                                                                                    
 18         printf("permission denied!\n");
 19     }
 20 
 21     return 0;
 22 }

2.2 Environment variable table (get all environment variable names and contents)

W> 11 int main(int argc ,char* argv[],char* env[])
   12 {
    
    
   13 
   14     for(int i=0; env[i]; i++)
   15     {
    
    
   16         printf("env[%d]-->%s\n",i,env[i]);                                                                                                         
   17     }
   18 
   19 }

1.
It can be seen that through the third parameter of the main function, the child process can also obtain all environment variables. This is also a way for child processes to inherit shell environment variables.

insert image description here

2.
Each process will be passed an environment table by the shell. The environment table is an array of character pointers, and each pointer points to an environment variable string ending with a slash 0

2.3 Third-party pointer variable environ (get all environment variable names and contents)

1.
The C language provides a third-party pointer variable called environ by default. When main is called, the system actually passes the environ variable as the third parameter of main to the main function. This involves array transmission in C language. For the question of parameters, environ is equivalent to another array name of the pointer array env[], and environ points to the first element of the env array. According to the address of the first element represented by the array name, environ is actually another array name of env.

insert image description here
2.
environ is a global secondary pointer initialized by default after the c or c++ program is compiled, pointing to the first element of the env array, because environ[ i ]=*( environ + i ), so another One way to get environment variables is as follows

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>                                                                                                                                  
  4                    
  5                       
  6 int main()         
  7 {
    
                      
  8  
  9     extern char** environ;
 10     for(int i=0; environ[i]; i++)
 11     {
    
                                
 12         printf("environ[%d]-->%s\n",i,environ[i]);
 13     }                                             
 14                                  
 15 }   

insert image description here

5. Change or increase environment variables through system calls

In the front, the environment variable is increased through the command-line export command. We can also change or increase the environment variable through the system call putenv(). This system call will be explained in detail in the following blog post.

Guess you like

Origin blog.csdn.net/erridjsis/article/details/128510634