赞
踩
Shebang(也称为解释器指令)是 Linux Shell 脚本文件的第一行指令,用于指定脚本文件的解释器(或者称为执行器)。Shebang 以 #! 开头,后面跟着解释器的路径和参数,例如:
#!/bin/bash
这是最常见的脚本写法,推荐写脚本时在第一行添加解释器指令。
在 Shebang 中可以指定不同的解释器和参数,以适应不同的需求。例如,可以指定 Python 解释器来执行 Python 脚本:
#!/usr/bin/env python
这表示使用 /usr/bin/env 命令来查找 Python 解释器,并使用该解释器来执行脚本文件。
Shebang 的作用是告诉操作系统如何执行脚本文件。当用户在终端中输入脚本文件名并按下回车键时,操作系统会查找脚本文件的 Shebang 行,并根据 Shebang 中指定的解释器来执行脚本文件。如果 Shebang 行中指定的解释器不存在或无法执行,则脚本文件将无法执行
查看当前登录用户的默认 shell 解释器:
# echo $SHELL
/bin/bash
(1)
#!/bin/bash
echo "My script PID is $$"
echo "Please enter a string:"
read input_string
echo "You entered: $input_string"
# 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:
# ps -ef | grep shell
root 27885 27235 0 21:03 pts/6 00:00:00 /bin/bash ./shell.sh
脚本文件的第一行添加一个特殊的注释,称为 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:
# ps -ef | grep shell
root 3160 27235 0 21:20 pts/6 00:00:00 sh shell.sh
以上都是常规的方式来运行脚本,通过脚本进程的命令行参数可以看到脚本解释器名和脚本文件名。
直接指明脚本解释器,只有一次脚本启动事件:
/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"
当shell脚本文件第一行没有 #! 开头,例如 #!/bin/bash时。
可以直接指明用什么脚本解释器来解释该脚本:
# bash shell.sh
My script PID is 5634
Please enter a string:
# ps -ef | grep shell
root 5634 27235 0 21:25 pts/6 00:00:00 bash shell.sh
此方式来运行脚本,通过脚本进程的命令行参数可以看到脚本解释器名和脚本文件名。
直接指明脚本解释器,只有一次脚本启动事件:
/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:
# ps -ef | grep 8032
root 8032 27235 0 21:30 pts/6 00:00:00 -bash
该脚本进程的命令行参数是 -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是不能解释其他脚本文件。
在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"
# 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:
可以看到用 source 命令执行脚本,其 pid 用的是当前终端 bash 的 pid。
在 Linux 中,source 命令用于读取并执行指定文件中的命令,通常用于执行启动脚本。启动脚本是一组命令,用于在系统启动时自动执行,例如设置环境变量、启动服务等。
source 命令只是读取并执行指定文件中的命令,不会创建新的子 shell,因此启动脚本中设置的环境变量和启动的服务都会在当前 shell 环境中生效。
(1)
当用 ./运行脚本时,会有一次额外的脚本启动事件,比如:
/usr/bin/bash shell.sh
备注:对于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
(2)
当在终端用 ./ 运行脚本时,shell脚本文件的第一行可以不用指定的解释器路径和名称,因为对于Linux 平台,当前终端的脚本一般默认都是 bash,这样第一行没有指定的解释器路径和名称时,也会用默认的脚本解释器去解释执行脚本。
./shell.sh //可以
bash shell.sh //可以
但是对于其他脚本,在终端用 ./ 运行时,当脚本文件的第一行没有指定的解释器路径和名称,是不能解释执行脚本。对于脚本文件的第一行没有指定的解释器路径和名称,可以直接在终端运行该脚本时指明脚本解释器。
./python.py //不可以
python python.py //可以
(3)
source 命令执行脚本只是读取并执行指定文件中的命令,不会创建新的子 shell。
source ./shell.sh
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。