Difference between "./" and "sh" in UNIX
sh file
executes a shell-script file in a new shell process.
. file
executes a shell-script file in the current shell process.
./file
will execute the file in the current directory. The file can be a binary executable, or it can start with a hashbang line (the first line of the file in form of #!....
, for example #!/usr/bin/ruby
in a file would signify the script needs to be executed as a Ruby file). The file needs to have the executable flag set.
For example, if you have the script test.sh
:
#!/bin/sh
TEST=present
and you execute it with sh test.sh
, you'd launch a new sh
(or rather bash
, most likely, as one is softlinked to the other in modern systems), then define a new variable inside it, then exit. A subsequent echo $TEST
prints an empty line - the variable is not set in the outer shell.
If you launch it using . test.sh
, you'd execute the script using the current shell. The result of echo $TEST
would print present
.
If you launch it using ./test.sh
, the first line #!/bin/sh
would be detected, then it would be exactly as if you wrote /bin/sh ./test.sh
, which in this case boils down to the first scenario. But if the hashbang line was, for example, #!/usr/bin/perl -w
, the file would have been executed with /usr/bin/perl -w ./test.sh
.
With sh , we can run a script that doesn’t have execute permission set on it, we run it as argument for sh, but ./ needs the permission as it is supposed to be an executable. In both cases, new shell will be created to run the script. See the below example:
root@ub18:~/shell# vi test1.sh
#!/bin/bash
my_var=hello
echo $my_var
#Shows the current shell processid
echo $$
root@ub18:~/shell# echo $$
1896
root@ub18:~/shell# sh test1.sh
hello
2093
root@ub18:~/shell# ./test1.sh
-su: ./test1.sh: Permission denied
root@ub18:~/shell# chmod +x ./test1.sh
root@ub18:~/shell# ./test1.sh
hello
2102
root@ub18:~/shell# ./test1.sh
hello
2103
root@ub18:~/shell# ./test1.sh
hello
2104
root@ub18:~/shell# sh test1.sh
hello
2106
In simple words, sh file1
executing sh command/executable with file1 as a parameter. In this case file1 doesn't require execute privilege as sh executable read and intercept the commands in the file.
./file1
its nothing but running/executing an executable file file1, hence it requires executable privileges. In this case it executes on the shell mentioned in the shebang #!/bin/sh
if its not mentioned then its on the current shell.
Hoping the above statements are not chaos :)