运行“bash script.sh”和“./script.sh”有什么区别?

use*_*136 59 bash executable shell-script

如果 script.sh 只是一些典型的东西

#!/bin/bash
echo "Hello World!"
Run Code Online (Sandbox Code Playgroud)

有没有首选的方式来运行脚本?我认为您首先必须对其进行 chmod 使其成为可执行文件?

hel*_*ylo 72

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


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

  • ./script.sh 使您的 shell 运行该文件,就好像它是一个常规的可执行文件一样。

shell fork 自己并使用系统调用(例如execve)使操作系统在 fork 进程中执行文件。操作系统将检查文件的权限(因此需要设置执行位)并将请求转发给程序加载器程序加载器查看文件并确定如何执行它。在 Linux 中编译的可执行文件以ELF幻数开头,而脚本以#!( hashbang )开头。hashbang 头意味着该文件是一个脚本,需要由 hashbang 之后指定的程序进行解释。这允许脚本本身告诉系统如何解释脚本。

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

  • bash script.sh使您的 shell 运行bashscript.sh作为命令行参数传递

因此操作系统将加载bash(甚至不查看script.sh,因为它只是一个命令行参数)。然后创建的bash进程将解释 ,script.sh因为它是作为命令行参数传递的。因为script.sh只是bash作为普通文件读取,所以不需要执行位。


不过我建议使用./script.sh,因为您可能不知道脚本需要哪个解释器。因此,让程序加载器为您确定。

  • 请注意,获取脚本可能会导致交互会话受到污染。例如,如果脚本更改了 PATH 环境变量,此更改将影响在源代码之后运行的命令。这种方法应该真正用于依赖副作用(环境设置脚本等)的情况。对于其他无法更改权限的情况,在 shebang 行中运行命令,后跟脚本名称是最安全的方法。 (13认同)
  • 请注意,如果您在当前目录中获取脚本,则不需要使用 **./**;就说`。脚本.sh`。但我同意那些不鼓励在不打算以这种方式调用的脚本上使用 **`.`** 命令的人。令我惊讶的是,没有人提到,如果脚本包含 `exit` 命令,并且您获取它,它可能会注销您。一个不太严重的问题是脚本是否执行了 `cd`,因为这也会影响父(交互式)shell。 (8认同)
  • @Dogeatcatworld 虽然这是真的,但运行`. ./script.sh` 与 `bash script.sh`(或 `./script.sh`。考虑脚本 `#!/usr/bin/python -V`<newline>`print test` . (5认同)
  • 如果未设置可执行位,您还可以通过执行“. ./script.sh”来运行脚本 (3认同)
  • @Dog 你是对的。点是内置命令“source”的快捷方式,它在当前 bash 进程中运行脚本。所以只需要可读位。 (2认同)

xx4*_*x4h 22

bash script.sh直接使用 bash 调用脚本。
./script.sh正在使用shebang#!/bin/bash来确定如何执行。

如果您真的想知道,如果您执行 a,bash script.sh您可以使用which bash.

所以在你的例子中它没有区别。是的,您必须chmod +x script.sh能够直接通过./script.sh.

  • 好吧,假设 `/bin/bash` 是你的 `$PATH` 中的第一个 `bash` 没有区别。 (2认同)

小智 10

创建一个文件 Delete_Self.sh 像这样:

 #!/bin/rm

 echo I am still here!
Run Code Online (Sandbox Code Playgroud)

运行此脚本,sh Delete_Self.sh您将看到“我还在这里!” 回响了。

使其可执行,然后运行它,因为./Delete_Self.sh您将看到没有任何回显,而文件Delete_Self.sh本身却消失了。

所以区别在于:

  • bash script.sh将忽略 #! 行,因为 bash 被指定为运行 script.sh 的程序。
  • ./script.sh将读取 #! 行来确定要运行的程序script.sh


小智 5

除了其他答案之外,了解通过./script.sh(i) 和source ./script.sh(ii) 运行脚本之间的区别很有用 - (i) 版本创建一个新的 shell 来运行命令,而 (ii) 在当前版本中运行它shell - 如果可执行文件更改了可执行文件退出后需要保留的环境变量,则该命令可能是强制的。例如,要激活 python conda 环境,必须使用以下命令:

source activate my_env
Run Code Online (Sandbox Code Playgroud)

source注意您可能会遇到的另一种替代方法是.内置的,即

. activate my_env
Run Code Online (Sandbox Code Playgroud)