0

I have a shell script that doesn't execute with ./script.sh but it requires . ./script.sh to execute.

What is the difference between ./ and . ./? I am using the MSYS2 environment on Windows. Please note the space between the dots. I know what ../, does and that doesn't solve the issue, as I am in the same directory as my executable.

Here's the output:

terminal output

JC2020
  • 9

2 Answers2

7

. is a source operator in Bash and multiple other POSIX shells:

$ help .
.: . 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.

It's always safer to do . ./script instead of . script because . searches PATH by default and you can run into name collisions:

$ echo echo hi > script
$ . script
bash: .: /usr/bin/script: cannot execute binary file
$ . ./script
hi

And because some shells do not search current directory be default:

$ mv script script-to-be-sourced
$ dash
$ . script-to-be-sourced
dash: 1: .: script-to-be-sourced: not found
2

The two are completely different, and can not be compared.

./ means the current directory.

. ./ means nothing like as it is, running will print the following error:

-bash: .: ./: is a directory

However, it needs to be broken down in two:

  • The . command
  • The ./ parameter

The . command is a shell built-in which is a synonym to the source command. It takes a file and not a directory as a parameter which is why you would get the error above.

A very command example that you might have seen is the following command:

$ . ~/.bashrc

And that is exactly synonym to

$ source ~/.bashrc

You can find their manual by running

man bash-builtins
        .  filename [arguments]
       source filename [arguments]
              Read and execute commands from filename in the current shell environment and return
              the exit status of the last command executed from filename.  If filename  does  not
              contain  a  slash,  filenames  in  PATH  are  used to find the directory containing
              filename.  The file searched for in PATH need not be executable.  When bash is  not
              in  posix  mode, the current directory is searched if no file is found in PATH.  If
              the sourcepath option to the shopt builtin command is turned off, the PATH  is  not
              searched.   If  any  arguments  are supplied, they become the positional parameters
              when filename is executed.  Otherwise the positional parameters are unchanged.  The
              return  status  is the status of the last command exited within the script (0 if no
              commands are executed), and false if filename is not found or cannot be read.

Lorenz Keel
  • 9,511
Dan
  • 14,180