0

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.

adam.hendry
  • 4,458
  • 5
  • 24
  • 51
  • In `. ./file1.sh`, the second dot _does_ refer to the current directory. I don't know how you mean wildcard expansion has to do with it. – Charles Duffy May 28 '21 at 02:44
  • 1
    `.` can search the PATH. Specifying a specific directory to find the file to be sourced in prevents that. – Charles Duffy May 28 '21 at 02:46
  • @CharlesDuffy I'm confused because my textbook says `.` doesn't mean anything, but I'm used to it meaning "the current working directory". Is the text wrong? – adam.hendry May 28 '21 at 03:06
  • @CharlesDuffy Oh you know what, I bet it's talking about file name _extensions_. I'll update the question with another piece I found in the text. – adam.hendry May 28 '21 at 03:11
  • @CharlesDuffy And thank you for the reference to the other same question. I couldn't find that. – adam.hendry May 28 '21 at 03:18
  • You're correct that leading a path, it does indeed mean "the fully working directory". – Charles Duffy May 28 '21 at 15:41
  • Also, parts of that textbook are completely, flatly wrong. `*.d` directories have nothing to do with "daemon scripts". I wouldn't trust it as far as you can throw it. – Charles Duffy May 28 '21 at 15:42
  • @CharlesDuffy Actually, the comment on `*.d` is from me, and I guess you're right. Technically, on folders, it means (loosely speaking) "this is a folder holding configuration files". Some files in those folders can be daemon scripts, but not all. And I actually think the book is fantastic! (Sorry to disagree). After clarifying this question about source, I've yet to find anything incorrect in it. Of course, some things get out dated from time to time, but the principles are rock solid. – adam.hendry May 28 '21 at 17:13
  • @CharlesDuffy And to back up my previous comment, here's some info: https://unix.stackexchange.com/questions/4029/what-does-the-d-stand-for-in-directory-names – adam.hendry May 28 '21 at 17:13
  • I assume the book is where you got `echo $a` from? It's an antipattern; see [I assigned a variable, but `echo $variable` shows something else!](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else) -- and that's not something getting out-of-date over time, it's been the case since the 1970s. – Charles Duffy May 28 '21 at 17:31
  • (BTW, you don't need to "back up" a correct statement that doesn't contradict anything I said). – Charles Duffy May 28 '21 at 17:36
  • @CharlesDuffy I made up `echo $a`. I was just typing fast. I didn't care about globbing, so I left it unquoted. That's not from the book. – adam.hendry May 28 '21 at 17:37
  • @CharlesDuffy Could I borrow your help on this one?: https://stackoverflow.com/questions/67743166/command-builtin-used-before-commands-in-all-if-statements – adam.hendry May 28 '21 at 17:38
  • Just saw this, and an accurate answer showed up a few seconds after following your link. :) – Charles Duffy May 28 '21 at 17:58
  • @CharlesDuffy Ah shucks! Well thanks anyway! I really appreciate the help! – adam.hendry May 28 '21 at 17:59

0 Answers0