I have bash script test.sh which does nothing special:

echo Hello!

If I run it like this . test.sh, it works.

kopparberg:dev marek$ . test.sh

If I run it like this ./test.sh, it does not.

kopparberg:dev marek$ ./test.sh 
-bash: ./test.sh: /bin/bash^M: bad interpreter: No such file or directory

What is the difference?

2 Answers 2


The difference between sourcing (. test.sh) the script and running it (test.sh or ./test.sh) is in the first line.

If you source the script the first line is only a comment and ignored. But if you run it, the first line is examined by the kernel for the first two characters, and if they are "#!", the rest of the line will be used as the path and the first argument for an interpreter. That is the kernel will look for an executable named /bin/bash and pass it the name of the script as first argument. Like this: /bin/bash ./test.sh.

This is what normally would happen and you are right, it should have the same effect for your script. But your script contains a problem: The first line ends with a DOS line ending (CR LF) instead of a unix line ending (LF). So the name of the interpreter, as the kernel sees it is /bin/bash^M which does not exist on your disk (^M stands for the spurious CR before the line ending). To make matters worse, the ^M character is usually invisible.

You can prove that this is the case with cat -v test.sh (which prints the substitution ^M for the invisible CR character).


The fist solution is an alias for "source" command.

The shebang is considered like a #comment for source

When you call the script with ./script, the shell will execute the script with the shebang #!/bin/bash

The error you gave seems to be a CRLF problem, you can run :

dos2unix script.sh

to remove Windows end-lines.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.