执行B之类的Bash脚本与B之类的Bash脚本一样,有什么区别?

A
> ./myscript

B
> source myscript


评论

您可能会阅读以下内容:bash.cyberciti.biz/guide/Source_command

#1 楼

采购脚本将在当前Shell进程中运行命令。

执行脚本将在新的Shell进程中运行命令。

如果希望脚本更改当前正在运行的Shell中的环境,请使用source。否则请使用execute。

如果您仍然感到困惑,请继续阅读。

术语

为了澄清有关执行语法和源语法的常见混淆:

./myscript


如果该文件是可执行文件并且位于当前目录中,则将执行myscript。前导点和斜杠(./)表示当前目录。这是必要的,因为当前目录通常不在$PATH中(并且通常不应该在myscript中)。目录位于$PATH中。

myscript


这将作为myscript的来源。该文件不必是可执行文件,但必须是有效的Shell脚本。该文件可以位于当前目录中,也可以位于$PATH中的目录中。

source myscript


这也将作为myscript的来源。此“拼写”是POSIX定义的官方拼写。 Bash将source定义为点的别名。

演示

考虑myscript.sh,其内容如下:

. myscript


在我们首先执行脚本之前,我们检查当前环境: >现在执行文件:

#!/bin/sh
# demonstrate setting a variable
echo "foo: "$(env | grep FOO)
export FOO=foo
echo "foo: "$(env | grep FOO)
# demonstrate changing of working directory
echo "PWD: "$PWD
cd somedir
echo "PWD: "$PWD


再次检查环境:

$ env | grep FOO
$ echo $PWD
/home/lesmana


变量FOO为未设置,并且工作目录未更改。

脚本输出清楚地表明已设置了变量并更改了目录。之后的检查表明未设置变量且目录未更改。发生了什么?所做的更改是在新的外壳中进行的。当前的shell产生了一个新的shell来运行脚本。该脚本在新的Shell中运行,对环境的所有更改都在新的Shell中生效。脚本完成后,新外壳将销毁。新外壳中对环境的所有更改都将被新外壳破坏。在当前外壳中仅打印输出文本。

现在我们获取文件来源:

$ ./myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir


再次检查环境:

$ env | grep FOO
$ echo $PWD
/home/lesmana


设置了变量FOO且工作目录已更改。

搜索脚本不会创建新的shell。所有命令都在当前Shell中运行,对环境的更改在当前Shell中生效。

请注意,在此简单示例中,执行的输出与脚本的来源相同。

另一个演示

请考虑以下脚本FOO

$ source myscript.sh
foo:
foo: FOO=foo
PWD: /home/lesmana
PWD: /home/lesmana/somedir


(特殊变量pid.sh扩展为当前正在运行的shell进程的PID)

首先打印当前shell的PID:

$ env | grep FOO
FOO=foo
$ echo $PWD
/home/lesmana/somedir


脚本:

#!/bin/sh
echo $$


执行脚本,注意PID:

$ echo $$
25009


再次来源:

$ source pid.sh
25009


再次执行:

$ ./pid.sh
25011


您可以看到执行脚本的源代码在同一进程中运行每次都会创建一个新流程。该新进程是为执行脚本而创建的新shell。编写脚本的源代码不会创建新的外壳,因此PID保持不变。

摘要

源代码和执行脚本都将逐行在脚本中运行命令,就像您逐行手动键入那些命令一样。

区别是:


执行脚本时,打开一个新的外壳,在新的外壳中键入命令,将输出复制回当前的外壳,然后关闭新的外壳。对环境的任何更改将仅在新外壳中生效,并且在新外壳关闭后将丢失。
在获取脚本源时,您正在当前外壳中键入命令。对环境的任何更改将生效并保留在您当前的Shell中。

如果希望脚本更改当前正在运行的Shell中的环境,请使用source。否则请使用execute。


另请参见:


https://stackoverflow.com/questions/6331075/why-do-you-need -dot-slash-before-script-name-to-run-it-in-bash
https://askubuntu.com/questions/182012/is-there-a-difference-between-and-source-流行于一切之后


评论


采购的一种用途是为脚本创建基本形式的配置文件。首先,将各种变量设置为默认值,然后使用诸如myscript.conf之类的源文件-源脚本可以具有可覆盖所需值的赋值语句。由于源脚本不是以#/ bin / bash开头,因此不建议直接执行它。

–LawrenceC
2014年6月4日13:24

因此,source有点像在全局范围内运行它,然后执行会创建一个新的本地范围。可以将其扩展为脚本中的功能吗?执行一个功能(通常)还是“来源”它?

–alaltalmind
2015年1月10日20:35



使用源myscript.sh和。 myscript.sh?

–霍洛韦
15年3月17日在9:37

如果使用bash,几乎没有区别。 source是在bash中加点的别名。

– Lesmana
15年3月17日在22:02

当人们提供如此详尽的示例时,即使喜欢我这样的Linux新手,我也喜欢它。谢谢!

–朱利叶斯
17年9月23日在16:00

#2 楼

执行脚本是在单独的子进程中运行脚本,即,调用shell的单独实例来处理脚本。这意味着脚本中定义的任何环境变量等都无法在父(当前)shell中进行更新。就像您键入脚本的内容一样。因此,源脚本不必是可执行的。但是,如果要执行它,它必须是可执行的。

如果当前外壳中有位置参数,则它们不变。

所以如果我有一个文件a.sh包含:

echo a $*


我这样做:

$ set `date`
$ source ./a.sh


我得到类似的东西: />
a Fri Dec 11 07:34:17 PST 2009


位置:

$ set `date`
$ ./a.sh


给我:

a


希望有帮助。

评论


尽管这个答案在各个方面都是正确的,但是我发现很难理解,因为它是使用另一个概念(设置位置参数)进行演示的,我认为这比采购和执行自身的差异更加令人困惑。

– Lesmana
10年8月16日在18:35

#3 楼

采购本质上与一次在命令提示符下键入脚本的每一行相同。返回的环境。

#4 楼

除上述内容外,
./myscript身份执行脚本需要文件myscript的执行权限,而源文件则不需要任何执行权限。这就是为什么在chmod +x myscript之前不需要source myscript

评论


没错,但是如果有问题,您可以随时运行bash myscript。

–丹尼尔·贝克♦
2012-2-23在7:31

#5 楼

采购后,您将获得脚本中定义的所有其他变量。
因此,如果您具有配置或函数定义,则应获取而不执行。执行不受父母环境的影响。

#6 楼

如果我没记错的话,执行脚本会以脚本文件作为参数在#!行中运行可执行文件(通常启动一个新的shell并将该脚本有效地源代码到新的shell中,就像#!/bin/sh一样);
该脚本在您当前的Shell环境中执行每一行,这对更改您当前的Shell很有用(例如,提供一种定义Shell函数和导出环境变量的方法)。

#7 楼

source命令在当前shell环境中执行提供的脚本(不是强制执行权限),而./命令在新shell中执行提供的可执行脚本。

另外,请检查以下答案,例如:https:/ /superuser.com/a/894748/432100