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

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

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

./test.sh

并执行这样的脚本:

. test.sh

我尝试了一个简单的两行脚本,看看是否可以找到差异:

#!/bin/bash
ls

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

答案1

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

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

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

./test.sh使用内置脚本运行单独的脚本和包含内置脚本之间最常见的区别.是,如果test.sh脚本设置了一些环境变量,则使用单独的进程时,仅设置子进程的环境,而使用脚本包含时,环境变量将被设置。鞋底外壳工艺已设定。如果您在调用脚本foo=bartest.sh及其echo $foo末尾添加一行,您将看到差异:

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

$ . ./test.sh
$ echo $foo
bar

答案2

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

答案3

我注意到的另一件事是,如果您有这样的别名:

# add into .bashrc_aliases
alias ls='ls -lht'

这样./test.sh你就会得到一个正常的ls输出(以及与当前 shell 不同的 PID):

auraham@pandora:~/iso$ ./test.sh 
dsl-4.4.10.iso  test.sh
3136 # PID

使用. test.sh. ./test.sh您将获得更详细的输出(以及与当前 shell 相同的 PID):

auraham@pandora:~/iso$ echo $$
2767 # shell PID

auraham@pandora:~/iso$ . test.sh 
total 50M
drwxrwxr-x  2 auraham auraham 4.0K Jul 30 15:41 .
-rwxrwxr-x  1 auraham auraham   32 Jul 30 15:41 test.sh
drwxr-xr-x 50 auraham auraham 4.0K Jul 30 15:30 ..
-rw-rw-r--  1 auraham auraham  50M Jul 28 17:24 dsl-4.4.10.iso
2767 # PID

答案4

通常,a./file只是指向文件的一种方式,在本例中,相当于 PWD(当前工作目录)路径后跟所使用的文件名。

$ pwd
/home/isaac/me/bin/

$ realpath ./file
/home/isaac/me/bin/file

行开头的路径(第一个参数或参数 0)也可能会向 shell 发出信号,要求其尝试执行该文件。如果它是一个 shell 脚本,那么 shell 很可能会加载它并在新的执行环境中执行它。如果它是其他形式的有效可执行文件,shell 将尝试通过内核exec命令执行它。

在命令行中添加一个初始点(仅当整个参数为零时才有效)将允许使用已存在的相同执行环境加载 shell 脚本(不是外部可执行文件)。

$ . ./file        # that exact same file as above, now it is sourced
$ source ./file   # an equivalent (but longer) command.

当然,如果路径中没有设置目录(不是以点开头),则会涉及一些搜索来查找要获取的特定文件。

在bash中:

如果文件名不包含斜杠,则使用 PATH 中的文件名来查找包含文件名的目录。

并且,如果在 POSIX 模式下,PWD 也用于搜索给filename定值。

相关内容