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 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.
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 $(command) and `command` in shell programming?
The backticks/gravemarks have been deprecated in favor of $()
for command substitution because $()
can easily nest within itself as in $(echo foo$(echo bar))
. There are other differences such as how backslashes are parsed in the backtick/gravemark version, etc.
See BashFAQ/082 for several reasons to always prefer the $(...) syntax.
Also see the POSIX spec for detailed information on the various differences.
difference between executing script using bash file.sh and ./file.sh
If "file.sh" is not executable then ./file.sh
will not work but bash file.sh
will.
If "file.sh" does not start with the line #!/bin/bash
(or another path to a valid bash interpreter) then ./file.sh
will not work but bash file.sh
will.
Basically, in order for a script to look like an executable file it must:
- Have execute permission.
- Start with the line
#!/path/to/interpreter
.
What is the difference b/w Bash and Shell script
"Shell script" is generic term for a script that's executed by a shell.
"Bash script" is a more specific term; it refers to a script that's executed by one specific shell, the Bash shell.
A shell is a command interpreter program. It can be used interactively (where the user types commands at a prompt, and the shell executes them), or as an interpreter for a script (where a series of commands are written in a file).
The Bourne shell is one of the older shells on UNIX (not the oldest, but we needn't worry about ancient history). Several other shells have been implemented as replacements for, or extensions of, the Bourne shell.
In particular, GNU Bash is perhaps the most commonly used shell these days. It implements the same features as the Bourne shell, plus a number of extensions.
A Bourne shell script typically starts with "Shebang" line:
#!/bin/sh
A Bash script typically starts with a Shebang that specifies the Bash shell:
#!/bin/bash
and may depend on features implemented by Bash but not by the Bourne shell.
(On some operating systems, /bin/sh
might be the same command as /bin/bash
.)
Not all Unix shells are based on the Bourne shell. In particular, csh
and its derivative tcsh
are largely incompatible with the Bourne-derived shells.
Bash has very little to do with Windows cmd
scripts, except that both Bash and cmd.exe
are both command interpreters.
What is the difference between using `sh` and `source`?
When you call source
or .
(the one is an alias to the other. source
cmd not POSIX - kind of bashism), you load and execute a shell script into the current shell process. So you can
- read variables set in the sourced script,
- use functions defined within it.
- and even execute forks and/or subprocess if script do this.
When you call sh
, you initiate a fork (sub-process or child) that runs a new session of /bin/sh
(which is often a symbolic link to bash
). In this case, environment variables set by the sub-script would be dropped when the sub-script terminate.
Caution: sh
could be a symlink to another shell.
Practical sample
For example, if you want to change current working directory by a specific manner, you could not do
$ cat <<eof >myCd2Doc.sh
#!/bin/sh
cd /usr/share/doc
eof
$ chmod +x myCd2Doc.sh
This won't do what you expect:
$ cd /tmp
$ pwd
/tmp
$ ~/myCd2Doc.sh
$ pwd
/tmp
because current working dir is part of environment and myCd2Doc.sh
would run in a subshell.
But:
$ cat >myCd2Doc.source <<eof
# Shell source file
myCd2Doc() {
cd /usr/share/doc
}
eof
$ . myCd2Doc.source
$ cd /tmp
$ pwd
/tmp
$ myCd2Doc
$ pwd
/usr/share/doc
Have a look at mycd
function!! (With bash completion based on Associative Array).
Execution level $SHLVL
$ cd /tmp
printf %b '\43\41/bin/bash\necho This is level \44SHLVL.\n' >qlvl.sh
$ bash qlvl.sh
This is level 2.
$ source qlvl.sh
This is level 1.
Recursion (when a script run from itself)
$ cat <<eoqlvl2 >qlvl2.sh
#!/bin/bash
export startLevel recursionLimit=5
echo This is level $SHLVL started:${startLevel:=$SHLVL}.
(( SHLVL < recursionLimit )) && ./qlvl2.sh
eoqlvl2
$ chmod +x qlvl2.sh
$ ./qlvl2.sh
This is level 2 started:2.
This is level 3 started:2.
This is level 4 started:2.
This is level 5 started:2.
$ source qlv2.sh
This is level 1 started:1.
This is level 2 started:1.
This is level 3 started:1.
This is level 4 started:1.
This is level 5 started:1.
A little futher
$ sed '$a ps --sid $SID fw' qlvl.sh >qlvl3.sh
$ chmod +x qlvl3.sh
$ export SID
$ read SID < <(ps ho sid $$)
$ echo $SID $$
8983 8983
( Current PID ($$
== process Id) are same identifier than SID (session ID). It's not alway true.)
$ ./qlvl3.sh
This is level 2.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10266 pts/10 S+ 0:00 \_ /bin/bash ./qlvl3.sh
10267 pts/10 R+ 0:00 \_ ps --sid 8983 fw
$ . qlvl3.sh
This is level 1.
PID TTY STAT TIME COMMAND
8983 pts/10 Ss 0:00 /bin/bash
10428 pts/10 R+ 0:00 \_ ps --sid 8983 fw
Dot .
is an alias of source
. So the only difference between two command are slash
replaced by space
.
And a final test:
$ printf %b '\43\41/bin/bash\necho Ending this.\nsle' \
'ep 1;exit 0\n' >finalTest.sh
$ bash finalTest.sh
Ending this.
$ source finalTest.sh
Ending this.
... You may notice a different behaviour between the two syntaxes. ;-)
Related Topics
How to Identify the User Who Owns a Process from /Proc/Pid
Cuda 5.0: Replacement for Cutil.H
Fail If a Script Expects Input or Entering Passwords
Shuffle Output of Find with Fixed Seed
Unusual Behaviour of Linux's Sort Command
Why a Linux Redirect Truncates the File
Grep for String and Open at the Corresponding Line
How to Make .Gitignore Configurable Based on Environment Variables
Shell Script Issue with Filenames Containing Spaces
Where Is $Path Set? Specifically Where Is My MAC Port Path Being Set
How to Merge Two Seperate - Yet Similar - Codebases into One Svn Rep
Automating Killall Then Killall Level 9
Rust Linux Version Glibc Not Found - Compile for Different Glibc/Libc6 Version
Curl Command Doesn't Work in Bash Script
Delete Files with Backslash in Linux
How to Install Python Package Installer Pip on Ubuntu 20.04 Linux
How to Find Common Rows in Multiple Files Using Awk
Bash Script to Remove Directories Based on Modified File Date