首页 > 解决方案 > Shell 脚本中 Dot(`.`)/Source 命令的参数

问题描述

我很困惑...我知道.不是 POSIX 文件通配符扩展字符,如*, ?,[][!]. 引用Arnold Robbins 和 Nelson HF Beebe。经典 Shell 脚本:释放 Unix 力量的隐藏命令(第 240 页)。奥莱利媒体。Kindle版。

MS-DOS、MS-Windows 和 OpenVMS 用户应该注意,Unix 文件名中的点 (.) 没有什么特别之处(除了开头的点,它“隐藏”文件);这只是另一个角色。例如 ls * 列出当前目录下的所有文件;你不需要 就像在其他系统上一样。

我也知道当前 shell 中的点 ( .) (或source) 命令源文件。例如,给定

#! /bin/sh
# file1.sh -- File to be sourced

a='123'

如果我跑

$ ./file1.sh

在终端中,我没有得到$a,因为我file1.sh在子shell中执行:

$ echo $a

$

但如果我改为运行

$ . file1.sh

然后我得到$a

$ echo $a
123
$

但是,为什么我需要在第二个脚本中使用点命令. ./file1.sh而不是在命令行中使用. file1.sh?我理解点命令搜索$PATHfile1.sh但我认为文件路径中的“点”不是 POSIX 通配符扩展(即不代表当前目录)。

如果在我的文件夹中,我有file1.sh并且是这样的:file2.shfile2.sh

#! /bin/sh

. file1.sh

我从终端的那个目录运行以下命令,我得到了

$ ./file2.sh
./file2.sh: line 3: .: file1.sh: file not found

但如果我跑

$ . file2.sh

现在我确实得到了$a

$ echo $a
123

此外,如果我file2.sh改为

#! /bin/sh
# file2.sh

# I don't know why this works...?
. ./file1.sh

然后我可以像第一种方式一样运行脚本并且它可以工作:

$ ./file2.sh
$ echo $a
123

有人可以向我解释这里发生了什么吗?

更新:

我相信文本的摘录可能指的是文件扩展名,而不是当前的工作目录符号。在这段摘录之上是文本中的内容(第 239 页):

如果您接触过 MS-DOS 下可用的简单命令行环境,您可能对*.*匹配当前目录中所有文件名的通配符很熟悉。Unix shell 通配符类似,但功能更强大。

Windows 使用文件扩展名的概念来确定使用什么程序来运行文件,但 Linux 没有。在 MS-DOS 中,搜索某种形式的东西会*.*返回一个文件,而在 Linux 中它可能是一个文件或一个目录。事实上,作为一个例子,Linux 中的几个文件夹以 . 结尾.d,表示它是一个包含“守护程序脚本”的文件夹。相比之下,在 Linux 上,shell 可以通过扫描文件顶部的shebang(例如)来确定用于运行文件的程序。#! /bin/sh

标签: shelldot

解决方案


推荐阅读