Difference between different ways of running shell script
sh test.sh
Tells the command to use sh
to execute test.sh
.
./test.sh
Tells the command to execute the script. The interpreter needs to be defined in the first line with something like #!/bin/sh
or #!/bin/bash
. Note (thanks keltar) that in this case the file test.sh
needs to have execution rights for the user performing this command. Otherwise it will not be executed.
In both cases, all variables used will expire after the script is executed.
. ./test.sh
Sources the code. That is, it executes it and whatever executed, variables defined, etc, will persist in the session.
For further information, you can check What is the difference between executing a bash script and sourcing a bash script? very good answer:
The differences are:
When you execute the script you are opening a new shell, type
the commands in the new shell, copy the output back to your current
shell, then close the new shell. Any changes to environment will take
effect only in the new shell and will be lost once the new shell is
closed.When you source the script you are typing the commands in your
current shell. Any changes to the environment will take effect and stay in your current shell.
What is the difference between ./ and . to run script in shell?
. cmd
vs
./cmd
are night and day different.
The first, is more like an "include", it executes the cmd within the context of the currently executing shell.
The second, is a path operation. ./cmd
is akin to /usr/local/bin/cmd
. the ./
is a path specifier.
In this case, it is saying that you are running a cmd
in the current directory, rather than searching the PATH env variable for cmd
.
When the cmd
is executed, it is forked and exec'd in to it's own process, unrelated to the current process. A completely different result from the first example.
Whats the difference between running a shell script as ./script.sh and sh script.sh
Running it as ./script.sh
will make the kernel read the first line (the shebang), and then invoke bash to interpret the script. Running it as sh script.sh
uses whatever shell your system defaults sh
to (on Ubuntu this is Dash, which is sh-compatible, but doesn't support some of the extra features of Bash).
You can fix it by invoking it as bash script.sh
, or if it's your machine you can change /bin/sh
to be bash and not whatever it is currently (usually just by symlinking it - rm /bin/sh && ln -s /bin/bash /bin/sh
). Or you can just use ./script.sh
instead if that's already working ;)
If your shell is indeed dash and you want to modify the script to be compatible, https://wiki.ubuntu.com/DashAsBinSh has a helpful guide to the differences. In your sample it looks like you'd just have to remove the function keyword.
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
.
What is the difference between these two commands which are used to run shell script?
The difference between the two invocations is that ./import.sh
is executing import.sh as a program, and . ./import.sh
is evaluating it in your shell.
If "import.sh" were an ELF program (a compiled binary, not a shell script), . ./import.sh
would not work.
If import.sh had a shebang at the top (like #!/bin/perl
), you'd be in for a nasty surprise and a huge number of error messages if you tried to do . ./import.sh
- unless the shebang happened to match your current shell, in which case it would accidentally work. Or if the Perl code were to somehow be a valid Bash script, which seems unlikely.
. ./import.sh
is equivalent to source import.sh
, and doesn't require that the file have the execute bit set (since it's interpreted by your already-running shell instead of spawned via exec
). I assume this is the source of your error. Another difference is that ./import.sh
runs in the current shell instead of a subshell, so any non-exported environment variables will affect the shell you used for the launch!
So, they're actually rather different. You usually want to ./import.sh
unless you know what you're doing and understand the difference.
What's the difference between: . [script] or source [script], bash [script] or $SHELL [script], and ./ [script] or [script]?
. script
and source script
execute the contents of script
in the current environment, i.e. without creating a subshell. On the upside this allows script
to affect the current environment, for example changing environment variables or changing the current work directory. On the downside this allows script
to affect the current environment, which is a potential security hazard.
bash script
passes script
to the bash
interpreter to execute. Whatever shebang is given by script
itself is ignored. ("Shebang" referring to the first line of script
, which could e.g. read #!/bin/bash
, or #!/usr/bin/perl
, or #!/usr/bin/awk
, to specify the interpreter to be used.)
$SHELL script
passes script
to whatever is your current shell interpreter to execute. That may, or may not, be bash
. (The environment variable SHELL
holds the name of your current shell interpreter. $SHELL
, if running bash, is evaluated to /bin/bash
, with the effect detailed in the previous paragraph.)
./script
executes the contents of a file script
in the current work directory. If there is no such file, an error is generated. The contents of $PATH
have no effect on what happens.
script
looks for a file script
in the directories listed in $PATH
, which may or may not include the current work directory. The first script
found in this list of directories is executed, which may or may not be the one in your current work directory.
Related Topics
Linux Umask for Sudo and Apache
Bash Script Command to Wait Until Docker-Compose Process Has Finished Before Moving On
How to Give to Some User Permissions Only to Subfolder
When Does a Process Handle a Signal
Is There an Os Command I Can Run to Determine If Running Inside a Xen Based Virtual Machine
How to Setup Cron Job on Amazon Linux Ami
Reading from a File in Assembly
Print Stdout/Stderr and Write Them to a File in Bash
Check The Output of "Make" and Exit Bash Script If It Fails
Linux X86 Nasm - Subroutine: Print a Dword from Eax
Golang Os/Exec, Realtime Memory Usage
Sharing Stdout Among Multiple Threads/Processes
Ssh Service Running on Multiple Ports with Custom Rules in Linux
Ubuntu/Fedora: How to Add Applications in The Menus
Install Sqlite3 Dev and Other Packages in Centos
How to Print $ in Shell Script
How to Create a Core File for My Crashed Program
What's The Meaning of 'C' in Result of Command "Ls -L /Dev/Tty'