I am confused...I know .
is not a POSIX file wildcard expansion character like *
, ?
,[]
, or [!]
. Quoting Arnold Robbins and Nelson H. F. Beebe. Classic Shell Scripting: Hidden Commands that Unlock the Power of Unix (p. 240). O'Reilly Media. Kindle Edition.
MS-DOS, MS-Windows, and OpenVMS users should note that there is nothing special about the dot (.) in Unix filenames (aside from the leading dot, which “hides” the file); it’s just another character. For example, ls * lists all files in the current directory; you don’t need . as you do on other systems.
I also know the dot (.
) (or source
) command sources files in the current shell. For example, given
#! /bin/sh
# file1.sh -- File to be sourced
a='123'
if I run
$ ./file1.sh
in the terminal, I don't get $a
because I executed file1.sh
in a subshell:
$ echo $a
$
but if I instead run
$ . file1.sh
then I do get $a
$ echo $a
123
$
However, why do I need to use the dot command in a second script like . ./file1.sh
instead of like on the command line . file1.sh
? I understand the dot command searches $PATH
for file1.sh
, but I thought "dot" in file paths was not a POSIX wildcard expansion (i.e. doesn't stand for current directory).
If in my folder I have file1.sh
and file2.sh
and file2.sh
is this:
#! /bin/sh
. file1.sh
and I run the following from that directory in the terminal, I get
$ ./file2.sh
./file2.sh: line 3: .: file1.sh: file not found
but if instead I run
$ . file2.sh
now I do get $a
$ echo $a
123
Furthermore, if I change file2.sh
to
#! /bin/sh
# file2.sh
# I don't know why this works...?
. ./file1.sh
then I CAN run the script as I did the first way and it works:
$ ./file2.sh
$ echo $a
123
Can somebody explain to me what is going on here?
UPDATE:
I believe the excerpt from the text may be referring to file name extensions and not the current working directory symbol. Above that excerpt is this in the text (p. 239):
If you’ve had any exposure to even the simple command-line environment available under MS-DOS, you’re probably familiar with the
*.*
wildcard that matches all filenames in the current directory. Unix shell wildcards are similar, but much more powerful.
Windows uses the concept of file name extensions to determine what program to use to run a file, but Linux does not. In MS-DOS, searching for something of the form *.*
returns a file, whereas in Linux it could be a file or a directory. In fact, as an example, several folders in Linux end in .d
, signifying it as a folder containing "daemon scripts". In contrast, on Linux, the shell can determine the program to use to run the file by scanning the shebang (e.g. #! /bin/sh
) at the top of the file.