The difference between #!/bin/bash and #!/bin/sh, source command and exec command

What is the meaning and difference between #!/bin/bash and #!/bin/sh at the beginning of a Linux script


1. Meaning


#!/bin/sh means that the script uses /bin/sh to interpret and execute, and #! , followed by the root of the path to the shell that interprets this script.


In fact, the #! in the first sentence is the interpreter program path to the script. The content of the script is interpreted by the interpreter. We can use various interpreters to write the corresponding script.


For example /bin/csh script, /bin/perl script, /bin/awk script, /bin/sed script, even /bin/echo and so on.


#!/bin/bash is the same.


2. The difference between


/bin/sh in the GNU/Linux operating system is a symbolic link to bash (Bourne-Again Shell), but in view of the complexity of bash, someone ported bash from NetBSD to Linux and renamed it dash (Debian Almquist Shell) , and recommend pointing /bin/sh to it for faster script execution. Dash Shell is much smaller than Bash Shell and is POSIX compliant.


Ubuntu inherits from Debian, so since Ubuntu 6.10 the default is Dash Shell.


It should be said that although /bin/sh is basically the same as /bin/bash, there are still different standards. Scripts marked #!/bin/sh should not use any features not specified by POSIX (commands such as let, but #!/bin/bash can). Debian used to use /bin/bash to change /bin/dash to use less disk space, provide less functionality, and get faster speed. But then there is a running problem after the shell script test. Because the original shell script (shell script) that can be run under the bash shell, there will still be some unexpected problems under /bin/sh, not 100% dual use.


The above can be understood in this way. Using the man sh command and the man bash command to observe, you can find that sh itself is dash, which better explains the changes after integrating the Debian system.


Supplementary
script test.sh content:
#!/bin/sh
source pcy.sh #pcy.sh does not exist
echo hello
execute ./test.sh, the screen output is:
./test.sh: line 2: pcy.sh: No such file or directory
It can be seen that in the case of #!/bin/sh, the source is unsuccessful and the code behind the source will not be run.
Modify the first line of the test.sh script to #!/bin/bash, execute ./test.sh again, the screen output is:
./test.sh: line 2: pcy.sh: No such file or directory
hello
It can be seen that in the case of #!/bin/bash, although the source is unsuccessful, the echo statement after the source is still run.
But then I tried to run sh ./test.sh again, this time the screen output is:
./test.sh: line 2: pcy.sh: No such file or directory
means that although #!/ is specified in the script bin/bash, but if you use sh to run, if the source is unsuccessful, the code behind the source will not be run.






Linux source command:


Common usage: source filepath or .filepath


Function: Make the current shell read the shell file whose path is filepath and execute all the statements in the file in turn, usually used to re-execute the just-modified initialization file to make it take effect immediately, without having to log out and back in. For example, when we modify the /etc/profile file and want it to take effect immediately without logging in again, we can use the source command, such as source /etc/profile.


The source command (from the C Shell) is a built-in command of the bash shell; the dot command (.), which is a dot (from the Bourne Shell), is another name for source. This can also be seen in usage.


 


The difference between source filepath and sh filepath and ./filepath:


    When the shell script has executable permissions, there is no difference between using sh filepath and ./filepath. ./filepath is because the current directory is not in the PATH, all "." are used to represent the current directory.


    sh filepath will recreate a subshell and execute the statements in the script in the subshell. The subshell inherits the environment variables of the parent shell, but the subshell is newly created, and the changed variables will not be brought back to the parent shell unless you use export.


    In fact, source filename simply reads the statements in the script and executes them in the current shell in turn, without creating a new subshell. Then all the new and changed variable statements in the script will be saved in the current shell.


 


For example:


    create a new test.sh script, the content is: A=1;


    modify its executable permission: chmod +x test.sh;


    after running sh test.sh, echo $A, the display is empty, because A=1 and It is not sent back to the current shell;


    after running ./test.sh, it has the same effect;


    running source test.sh or .test.sh, and then echo $A, it will display 1, indicating that the variable with A=1 is in the current shell middle;




Related to the exec command in Linux:





Both exec and source belong to bash internal commands (builtins commands). Enter man exec or man source under bash to view all internal command information.
  The commands of the bash shell are divided into two categories: external commands and internal commands. External commands are implemented through system calls or stand-alone programs such as sed, awk, etc. Internal


commands are implemented by special file formats (.def) such as cd, history, exec, etc.


  Before explaining the difference between exe and source, first explain the concept of fork.


  fork is a linux system call used to create child processes. The child process is a copy of the parent process, which


obtains certain resource allocations from the parent process and inherits the environment of the parent process. The only difference between the child process and the parent process is the pid (process id).


  Environment variables (variables passed to the child process, heredity is the fundamental difference between local variables and environment variables) can only be passed from the parent process to the child process in one direction. No matter how the environment


variables change, it will not affect the environment variables of the parent process.


  Shell script:


  There are two ways to execute shell scripts, one is to generate a new shell, and then execute the corresponding shell scripts; the other is


to enabling other shells.


  The way to generate a new shell and then execute scripts is to add the following statement at the beginning of the scripts file


  #!/bin/sh


  The general script file (.sh) is this usage. This method first enables a new sub-shell (new subprocess), and then executes commands under it.


  Another method is the source command mentioned above, no new shell is generated, and all commands are executed under the current shell.


  source:


  The source command is the dot (.) command.


  Enter man source under bash, find the source command explanation, you can see the explanation "Read and execute commands from filename in the


current shell environment and ...". It can be known from this that the source command executes each command in the parameter file in the current process, rather than starting a child


process (or sub-shell).


  exec:


  Enter man exec under bash, find the explanation of the exec command, you can see the explanation of "No new process is created.", which means that the exec


command does not generate new child processes. So what is the difference between exec and source? The


  exec command will close the current shell process when it is executed, and then switch to the following command to continue execution.


 


The system call exec is to replace the original process with a new process, but the PID of the process remains unchanged. Therefore, it can be considered that the exec system call does not create a new


process , but just replaces the contents of the original process context. The code segment, data segment, and stack segment of the original process are replaced by the new process.


  A process mainly includes the following aspects:


  (1) An executable program


  (2) All data associated with the process (including variables, memory, buffers)


  (3) Program context (program counter PC, where program execution is saved)

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325827321&siteId=291194637