“.myscript”和“./myscript”之间的区别

“.myscript”和“./myscript”之间的区别

我对“只有一个点 - 空格 - shell 脚本名称”(如. myshellscript)和“shell 脚本路径”(如./myshellscript)命令感到困惑。

他们是为了什么?我注意到该命令. myshellscript即使使用 -rw-rw-r-- 也会执行 shell 脚本。但./myshellscript事实并非如此。所以我很困惑。

答案1

help source说:

source: source filename [arguments]
    Execute commands from a file in the current shell.

    Read and execute commands from FILENAME in the current shell.  The
    entries in $PATH are used to find the directory containing FILENAME.
    If any ARGUMENTS are supplied, they become the positional parameters
    when FILENAME is executed.

    Exit Status:
    Returns the status of the last command executed in FILENAME; fails if
    FILENAME cannot be read.

source是 的同义词.,这意味着您可以同时写

. myshellscript

或者

source myshellscript

它们的作用:source读取文件的每一行(逐行)并在当前 shell 中执行它。

./myshellscript 执行当前目录中的文件(如果有权限)。这也可以是

/tmp/foo/bar/myshellscript

(执行myshellscript目录中的文件/tmp/foo/bar)或

/usr/local/bin/myshellscript

这意味着,这里的点只是当前目录。因此执行当前目录中./myshellscript调用的文件。myshellscript

例如尝试

cd .

更改为当前目录(没有真正的更改;-))或

ls .

其中列出了当前目录的内容。


正如@Alvin Wong 评论的那样:你可以尝试这个脚本

#!/bin/foobarNonExisting

echo "This is the Shell that executes me:"
echo $SHELL

with.sourceto see,它不读取 shebang。它只使用您当前的 shell。执行脚本本身会导致错误。

答案2

其他人表示区别在于采购与执行,但没有人概述其中的区别功能性的差异。

最大的功能差异是exitcd如果您获取当前运行的 shell,则 、 和 变量赋值将影响当前运行的 shell,但如果执行它,则不会影响。要进行演示,请尝试以下操作:

$ cat test.sh
#!/bin/bash

mkdir -p test
cd test
pwd

foo=bar
echo script foo: $foo

$ ./test.sh
/Users/kevin/test
script foo: bar
$ echo $foo

$ pwd
/Users/kevin
$ . test.sh
/Users/kevin/test
script foo: bar
$ echo $foo
bar
$ pwd
/Users/kevin/test
$ 

现在试试这个:

$ cat test.sh
#!/bin/bash
exit
$ ./test.sh
$ . test.sh

[Process completed]

正如您所看到的,exit在执行的脚本中将完成该脚本,但如果您使用 来获取脚本exit,它将退出当前的 shell!

答案3

在 bash 中,.source功能上执行相同的工作——在当前 shell 内运行脚本。

./foo在另一个 shell 中运行,因为您的 shell 在执行之前分叉。

如果您的脚本应该是可移植的,请始终使用..source是 bash 的同义词,但在 POSIX 中不存在。

答案4

有很多答案解释说. ~/bin/script.sh相当于source ~/bin/script.sh.这是的解释为什么

我有几个用于测试的集群,我使用环境变量来指向它们。通常,当您运行脚本时,其中设置的任何变量都保留在该脚本的范围内。在示例中:

$ echo $MYFIELD #Nothing set

$ cat test.sh
export MYFIELD=foo #This would set it
$ ./test.sh
$ echo $MYFIELD #Didn't work because the script didn't carry it back to its parent

$ . ./test.sh
$ echo $MYFIELD #When run as a sourced script, this stayed in the context of my current shell
foo

通过这种方式,我可以. ~/env/cluster7在该集群上键入并运行我想要的任何命令,然后键入. ~/env/cluster3以更改所有环境变量以指向另一个环境变量,而无需手动设置它们。

请注意“。”行首后跟空格被解释为命令。这是可以的,因为您永远不会执行唯一可以这样命名的文件:当前目录。但是,在任何其他上下文中,例如没有后续空格或在命令行后面的任何点,它指的是路径,因此. ./test.sh.由于它被 bash 视为命令,. test.sh因此也有效。

相关内容