当前位置:   article > 正文

Linux shell脚本几种运行方式_linux 脚本 shebang

linux 脚本 shebang

一、第一行添加解释器指令

Shebang(也称为解释器指令)是 Linux Shell 脚本文件的第一行指令,用于指定脚本文件的解释器(或者称为执行器)。Shebang 以 #! 开头,后面跟着解释器的路径和参数,例如:

#!/bin/bash
  • 1

这是最常见的脚本写法,推荐写脚本时在第一行添加解释器指令。
在 Shebang 中可以指定不同的解释器和参数,以适应不同的需求。例如,可以指定 Python 解释器来执行 Python 脚本:

#!/usr/bin/env python
  • 1

这表示使用 /usr/bin/env 命令来查找 Python 解释器,并使用该解释器来执行脚本文件。

Shebang 的作用是告诉操作系统如何执行脚本文件。当用户在终端中输入脚本文件名并按下回车键时,操作系统会查找脚本文件的 Shebang 行,并根据 Shebang 中指定的解释器来执行脚本文件。如果 Shebang 行中指定的解释器不存在或无法执行,则脚本文件将无法执行

查看当前登录用户的默认 shell 解释器:

# echo $SHELL
/bin/bash
  • 1
  • 2

(1)

#!/bin/bash

echo "My script PID is $$"

echo "Please enter a string:"
read input_string

echo "You entered: $input_string"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
# ps
  PID TTY          TIME CMD
27235 pts/6    00:00:00 bash
27862 pts/6    00:00:00 ps
# ./shell.sh
My script PID is 27885
Please enter a string:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
# ps -ef | grep shell
root     27885 27235  0 21:03 pts/6    00:00:00 /bin/bash ./shell.sh
  • 1
  • 2

脚本文件的第一行添加一个特殊的注释,称为 shebang(也叫 hashbang)。这个注释以 #! 开头,后面跟着解释器的路径和名称,例如 #!/bin/bash。这告诉 Linux 系统,这个脚本需要使用 Bash 解释器来执行。

Linux 系统会根据 shebang 中指定的解释器路径和名称,找到 Bash 解释器,并使用它来执行脚本。

当用 ./运行脚本时,且第一行指定的解释器路径和名称,有两次脚本启动事件,两次执行 exec 系统调用的pid都一样:
/usr/bin/bash shell.sh
/usr/bin/bash /usr/bin/bash cmd: /bin/bash ./shell.sh

对于 python 脚本也是:
当用 ./运行脚本时,且第一行指定的解释器路径和名称,有两次脚本启动事件,两次执行 exec 系统调用的pid都一样:
/usr/bin/bash python.py
/usr/bin/bash /usr/bin/python2.7 cmd: /usr/bin/python ./python.py

进程启动是会有一次读取文件的事件
先有脚本解释器读取脚本文件事件。
然后脚本解释器启动脚本文件事件。
read -> exec

(2)
也可以直接指明脚本解释器:

# sh shell.sh
My script PID is 3160
Please enter a string:
  • 1
  • 2
  • 3
# ps -ef | grep shell
root      3160 27235  0 21:20 pts/6    00:00:00 sh shell.sh
  • 1
  • 2

以上都是常规的方式来运行脚本,通过脚本进程的命令行参数可以看到脚本解释器名和脚本文件名。

直接指明脚本解释器,只有一次脚本启动事件:
/usr/bin/bash /usr/bin/bash cmd:bash shell.sh

进程启动是会有读取文件的事件,对于直接指明脚本解释器:
先有脚本解释器启动脚本文件事件。
然后脚本解释器读取脚本文件事件。

exec -> read

二、第一行没有添加解释器指令

(1)

echo "My script PID is $$"

echo "Please enter a string:"
read input_string

echo "You entered: $input_string"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

shell脚本文件第一行没有 #! 开头,例如 #!/bin/bash时。

可以直接指明用什么脚本解释器来解释该脚本:

# bash shell.sh
My script PID is 5634
Please enter a string:
  • 1
  • 2
  • 3
# ps -ef | grep shell
root      5634 27235  0 21:25 pts/6    00:00:00 bash shell.sh
  • 1
  • 2

此方式来运行脚本,通过脚本进程的命令行参数可以看到脚本解释器名和脚本文件名。

直接指明脚本解释器,只有一次脚本启动事件:
/usr/bin/bash /usr/bin/bash cmd:bash shell.sh

(2)
当没有指明用什么脚本解释器来解释该脚本时,而直接用 ./ 来运行该脚本时:

# ps
  PID TTY          TIME CMD
27235 pts/6    00:00:00 bash

# ps -ef | grep 27235
root     27235 27219  0 21:02 pts/6    00:00:00 -bash

# ./shell.sh
My script PID is 8032
Please enter a string:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
# ps -ef | grep 8032
root      8032 27235  0 21:30 pts/6    00:00:00 -bash
  • 1
  • 2

该脚本进程的命令行参数是 -bash 了,命令行参数没有脚本解释器的名字和脚本文件的路径。
查看终端脚本解释器的命令行参数也是 -bash。

“-bash” 不是一个脚本进程命令行参数,而是 Bash shell 的提示符。
当你在终端中打开一个 Bash shell 时,其命令行参数就是"-bash",它会显示一个提示符,让你可以输入命令。

如果 Linux shell 脚本文件的第一行没有以 #! 开头指定解释器路径和名称,当你使用 ./ 命令运行一个没有指定解释器的脚本文件时,Linux 系统会使用当前登录用户的默认 shell 解释器来执行脚本。因此,在执行脚本时,命令行提示符会显示 “-bash”,并且脚本的命令行参数会被设置为 “-bash”。

例如,如果当前登录用户的默认 shell 是 Bash,而你使用 ./myscript.sh 命令运行一个没有指定解释器的脚本文件 myscript.sh,那么 Linux 系统会使用 Bash 解释器来执行脚本。

因此以上方式运行脚本的命令行参数是 -bash ,不会显示脚本解释器的名字和脚本文件的路径。脚本被解释成一个交互式 shell 的情况。在这种情况下,命令行提示符会变成 -bash。

当你使用 ./ 命令运行一个没有指定解释器的 Linux shell 脚本文件时,Linux 系统会默认使用当前登录用户的默认 shell 解释器来执行脚本。如果脚本文件的第一行没有以 #! 开头指定解释器路径和名称,那么系统会使用当前登录用户的默认 shell 解释器来执行脚本。

在这种情况下,当你执行脚本时,命令行提示符会显示 “-bash”,而脚本的命令行参数会被设置为 “-bash”。

在执行脚本时,命令行提示符会显示 “-bash”,而脚本的命令行参数会被设置为 “-bash”。这是因为在这种情况下,系统会使用当前登录用户的默认 shell 解释器来执行脚本,而不是使用指定的解释器。

有一次进程启动事件:/usr/bin/bash shell.sh

通过./ 来运行该脚本时才有进程启动事件:/usr/bin/bash shell.sh。

备注对于脚本文件,当脚本文件第一行没有指明用什么脚本解释器来解释该脚本时,而直接用 ./ 来运行该脚本时,只有shell脚本能成功执行,其他的脚本不可以运行,因为没有对应的脚本解释器来解释对应的脚本,而shell脚本能成功执行是因为Linux下终端默认的脚本是Bash。Bash是不能解释其他脚本文件。

三、source 和 .运行脚本

在Linux中,source命令用于在当前shell环境中执行指定的脚本文件,通常用于加载shell配置文件或其他一些需要在当前shell环境中生效的操作。

source命令和 . 可以替代,效果一样。

source命令是内置命令:

#!/bin/bash

echo $0

echo "My script PID is $$"

echo "Please enter a string:"
read input_string

echo "You entered: $input_string"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
# type source
source 是 shell 内嵌

# ps
  PID TTY          TIME CMD
 4815 pts/2    00:00:00 ps
30823 pts/2    00:00:00 bash

# source shell1.sh
-bash
My script PID is 30823
Please enter a string:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

可以看到用 source 命令执行脚本,其 pid 用的是当前终端 bash 的 pid。

在 Linux 中,source 命令用于读取并执行指定文件中的命令,通常用于执行启动脚本。启动脚本是一组命令,用于在系统启动时自动执行,例如设置环境变量、启动服务等。

source 命令只是读取并执行指定文件中的命令,不会创建新的子 shell,因此启动脚本中设置的环境变量和启动的服务都会在当前 shell 环境中生效。

总结

(1)
当用 ./运行脚本时,会有一次额外的脚本启动事件,比如:

/usr/bin/bash shell.sh
  • 1

备注:对于Linux 平台,用 ./ 运行二进制可执行文件或者脚本文件时,都会有一次 bash 启动 二进制可执行文件或者脚本文件名的事件。

通常运行脚本时,要么在命令行直接指明用什么脚本解释器,要么用脚本文件的第一行指定的解释器路径和名称,找到对应解释器执行脚本,这种运行脚本方式会有一次脚本启动事件:

/usr/bin/bash /usr/bin/bash cmd: /bin/bash ./shell.sh
or
/usr/bin/bash /usr/bin/python2.7 cmd: /usr/bin/python ./python.py
  • 1
  • 2
  • 3

(2)
当在终端用 ./ 运行脚本时,shell脚本文件的第一行可以不用指定的解释器路径和名称,因为对于Linux 平台,当前终端的脚本一般默认都是 bash,这样第一行没有指定的解释器路径和名称时,也会用默认的脚本解释器去解释执行脚本。

./shell.sh         //可以
bash shell.sh	   //可以
  • 1
  • 2

但是对于其他脚本,在终端用 ./ 运行时,当脚本文件的第一行没有指定的解释器路径和名称,是不能解释执行脚本。对于脚本文件的第一行没有指定的解释器路径和名称,可以直接在终端运行该脚本时指明脚本解释器。

./python.py        //不可以
python python.py   //可以
  • 1
  • 2

(3)
source 命令执行脚本只是读取并执行指定文件中的命令,不会创建新的子 shell。

source ./shell.sh
  • 1
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/article/detail/51453
推荐阅读
相关标签
  

闽ICP备14008679号