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


42

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

#!/bin/bash
echo "Hello World!"

有运行脚本的首选方法吗?我认为您首先必须对其进行chmod修改,使其可以执行?

Answers:


56

对于您的特定脚本,这两种方法都可以工作,除了./script.sh需要执行和可读位的方式之外,而bash script.sh仅需要可读位的即可。


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

  • ./script.sh 使您的外壳程序像正常可执行文件一样运行文件。

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

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

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

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


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


3
如果未设置可执行位,则还可以通过执行“ ../script.sh”来运行脚本
狗吃猫世界

1
@狗你是正确的。点是内置命令“ source”的快捷方式,该命令在当前bash进程中运行脚本。因此,仅需要可读位。
2014年

5
@Dogeatcatworld而这是真的,运行. ./script.sh是不一样的东西bash script.sh(或./script.sh认为剧本。#!/usr/bin/python -V<换行符> print test
凯西

12
请注意,采购脚本可能会导致交互式会话受到污染。例如,如果脚本更改了PATH环境变量,则此更改将影响遵循源代码运行的命令。对于依赖副作用(环境设置脚本等)的情况,应该真正保留这种方法。对于其他无法更改权限的情况,最安全的方法是在shebang行中运行命令,后跟脚本名称。
ctt

6
需要注意的是,如果在当前目录源脚本,你不需要使用./ ; 只是说. script.sh。但我同意那些不赞成.在脚本中使用该命令的人,这些脚本并非旨在以这种方式被调用。令我惊讶的是,没有人提到,如果脚本包含exit命令并且您将其来源,它可能会将您注销。一个较小的问题是脚本是否执行cd,因为这也会影响父(交互)shell。
斯科特

18

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

如果您确实想知道,执行时将执行哪个二进制文件,则bash script.sh可以使用找出which bash

因此,在您的示例中,这没有什么区别。是的,您必须chmod +x script.sh能够直接通过执行它./script.sh


2
好吧,假设这/bin/bashbash您中的第一个没有什么区别$PATH
cjm 2014年

你是对的。#!/bin/bash只有在有/bin/bash
xx4h

即使未设置执行位,我系统上的Bash(版本4.2.37)也可以执行脚本。为什么说需要执行位?
2014年

是的,仅需通过调用执行位./script.sh
xx4h 2014年

4

创建一个文件Delete_Self.sh,如下所示:

 #!/bin/rm

 echo I am still here!

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

使它可执行,然后运行它,因为./Delete_Self.sh文件Delete_Self.sh本身不见了,您将看不到任何回声。

所以区别是:

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

+1是一个很好的例子
ThisaruG

1

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

source activate my_env

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

. activate my_env
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.