bash script.sh 与 ./script.sh 与 #shebang

bash script.sh 与 ./script.sh 与 #shebang

假设我现在在 bash shell 中并执行以下操作

[me@server]$ bash script.sh

q1)是否创建了一个新的子 bash 进程来执行该脚本?

如果我做了

[me@server]$ ./script.sh

q2)是否创建了一个新的子 bash 进程来执行该脚本?

q3) 那么这两种方法有什么区别?

答案1

点斜线解释

你所做的不同之处在于,

使用sh,你正在运行一个程序,它将interpret the lines in your script像你在终端的交互提示中输入的那样,

使用 ./ 可以创建一个快捷方式,假设脚本就在你当前所在的目录中,并且它是可执行的(因为例如你发出了 chmod +x myscript.sh),

附加信息来自回答 :

对于您的特定脚本,两种方式都可以工作,但 ./script.sh 需要执行和可读位,而 bash script.sh 只需要可读位。

权限要求不同的原因在于解释脚本的程序如何加载:

./script.sh 让您的 shell 像运行常规可执行文件一样运行该文件。shell 会自行分叉并使用系统调用(例如 execve)让操作系统在分叉的进程中执行该文件。操作系统将检查文件的权限(因此需要设置执行位)并将请求转发给程序加载器,后者查看文件并确定如何执行它。在 Linux 中,编译的可执行文件以 ELF 魔数开头,而脚本以 #!(哈希邦)开头。哈希邦标头表示该文件是一个脚本,需要由哈希邦后指定的程序进行解释。这允许脚本本身告诉系统如何解释该脚本。

使用您的脚本,程序加载器将执行 /bin/bash 并传递 ./script.sh 作为命令行参数。

bash script.sh 使您的 shell 运行 bash 并将 script.sh 作为命令行参数传递,因此操作系统将加载 bash(甚至不会查看 script.sh,因为它只是一个命令行参数)。然后,创建的 bash 进程将解释 script.sh,因为它是作为命令行参数传递的。由于 script.sh 仅由 bash 作为常规文件读取,因此不需要执行位。

答案2

  1. 创建一个子 bash 进程
  2. 与上面相同(由于 shebang)
  3. 这两个是等效的,如果你不想 fork 子进程,或者想保留环境值script.sh,请使用

    . ./script.sh
    

但要小心

  • 如果script.sh调用exit,你将退出当前shell。
  • 如果 shell 结束时没有错误,您将返回到初始 shell。

相关内容