采购('.' 或 'source')和在 bash 中执行文件有什么区别?

Nat*_*han 88 shell bash

执行这样的脚本有什么区别:

./test.sh

并执行这样的脚本:

. test.sh?

我尝试了一个简单的两行脚本,看看是否能找到不同之处:

#!/bin/bash
ls
Run Code Online (Sandbox Code Playgroud)

但两者. test.sh./test.sh返回相同的信息。

Gil*_*il' 98

./test.shtest.sh作为单独的程序运行。如果文件test.sh以 .bash 开头,它可能恰好是一个 bash 脚本#!/bin/bash。但它可能完全是另一回事。

. ./test.shtest.sh在运行的 bash 实例中执行文件的代码。它的工作方式就好像内容文件test.sh已被包含在文本中而不是. ./test.sh行中。(几乎:有一些不同的细节,例如 的值$BASH_LINENOreturn内置函数的行为。)

source ./test.sh. ./test.shbash相同(在其他 shell 中,source可能略有不同或完全不存在;.因为包含在 POSIX 标准中)。

运行./test.sh带有.内置脚本的单独脚本和包含带有内置脚本的脚本之间最常见的区别是,如果test.sh脚本设置了一些环境变量,那么对于单独的进程,只会设置子进程的环境,而对于包含脚本的脚本,会设置环境变量的唯一壳进程设置。如果您在调用脚本foo=bartest.shecho $foo末尾添加一行,您将看到不同之处:

$ cat test.sh
#!/bin/sh
foo=bar
$ ./test.sh
$ echo $foo

$ . ./test.sh
$ echo $foo
bar
Run Code Online (Sandbox Code Playgroud)

  • 另外在脚本中添加 `echo $$` 将非常清楚地显示差异。`$$` 变量保存当前 shell 的 PID。 (21认同)

cho*_*oba 11

以第一种方式运行脚本将其作为子进程运行。另一方面,Sourcing(第二种方式)运行脚本,就像您将其所有命令输入到当前 shell 一样 - 如果脚本设置了一个变量,它将保持设置,如果脚本退出,您的会话将退出。请参阅help .文档。