File execution with dot space versus dot slash
Let's start with how the command path works and when it's used. When you run a command like:
ls /tmp
The ls
here doesn't contain a / character, so the shell searches the directories in your command path (the value of the PATH environment variable) for a file named ls
. If it finds one, it executes that file. In the case of ls
, it's usually in /bin
or /usr/bin
, and both of those directories are typically in your path.
When you issue a command with a / in the command word:
/bin/ls /tmp
The shell doesn't search the command path. It looks specifically for the file /bin/ls
and executes that.
Running ./A
is an example of running a command with a / in its name. The shell doesn't search the command path; it looks specifically for the file named ./A
and executes that. "." is shorthand for your current working directory, so ./A
refers to a file that ought to be in your current working directory. If the file exists, it's run like any other command. For example:
cd /bin./ls
would work to run /bin/ls
.
Running . A
is an example of sourcing a file. The file being sourced must be a text file containing shell commands. It is executed by the current shell, without starting a new process. The file to be sourced is found in the same way that commands are found. If the name of the file contains a /, then the shell reads the specific file that you named. If the name of the file doesn't contain a /, then the shell looks for it in the command path.
. A # Looks for A using the command path, so might source /bin/A for example. ./A # Specifically sources ./A
So, your script tries to execute . B
and fails claiming that B
doesn't exist, even though there's a file named B
right there in your current directory. As discussed above, the shell would have searched your command path for B
because B
didn't contain any / characters. When searching for a command, the shell doesn't automatically search the current directory. It only searches the current directory if that directory is part of the command path.
In short, . B
is probably failing because you don't have "." (current directory) in your command path, and the script which is trying to source B
is assuming that "." is part of your path. In my opinion, this is a bug in the script. Lots of people run without "." in their path, and the script shouldn't depend on that.
Edit:
You say the script uses ksh
, while you are using bash
. Ksh follows the POSIX standard--actually, KSH was the basis for the POSIX standard--and always searches the command path as I described. Bash has a flag called "POSIX mode" which controls how strictly it follows the POSIX standard. When not in POSIX mode--which is how people generally use it--bash will check the current directory for the file to be sourced if it doesn't find the file in the command path.
If you were to run bash -posix
and run . B
within that bash instance, you should find that it won't work.