Differencebetween These Two Commands Which Are Used to Run Shell Script

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:

  1. Have execute permission.
  2. 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



Leave a reply



Submit