Differencebetween "./Somescript.Sh" and ". ./Somescript.Sh"

What is the difference between ./somescript.sh and . ./somescript.sh

./setup.sh runs the script, a new shell will be started that runs the script. That new shell cannot affect the parent shell that started the script.

. ./setup.sh is a shorthand for source ./setup.sh and it will run the script in the current shell, instead of starting a new shell to run it. This means the script can alter the behavior of the current shell, e.g. set new environment variables.

What is the difference between ./a.sh and . ./a.sh?

. path/to/script sources the file (executes it in the same shell). The other call forks a new shell process which executes the script.

Invoking a script in a child process will make its variables not available to the parent process. Sourcing a script will introduce and change variables in the same parent process.

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 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.

Why does my Bash code fail when I run it with 'sh'?

TL;DR: Since you are using Bash specific features, your script has to run with Bash and not with sh:

$ sh myscript.sh
myscript.sh: 2: myscript.sh: Bad substitution

$ bash myscript.sh
ffmpeg -i bar.mp4 bar.mp3
ffmpeg -i foo.mp4 foo.mp3

See Difference between sh and Bash. To find out which sh you are using: readlink -f $(which sh).

The best way to ensure a bash specific script always runs correctly

The best practices are to both:

  1. Replace #!/bin/sh with #!/bin/bash (or whichever other shell your script depends on).
  2. Run this script (and all others!) with ./myscript.sh or /path/to/myscript.sh, without a leading sh or bash.

Here's an example:

$ cat myscript.sh
#!/bin/bash
for i in *.mp4
do
echo ffmpeg -i "$i" "${i/.mp4/.mp3}"
done

$ chmod +x myscript.sh # Ensure script is executable

$ ./myscript.sh
ffmpeg -i bar.mp4 bar.mp3
ffmpeg -i foo.mp4 foo.mp3

(Related: Why ./ in front of scripts?)

The meaning of #!/bin/sh

The shebang suggests which shell the system should use to run a script. This allows you to specify #!/usr/bin/python or #!/bin/bash so that you don't have to remember which script is written in what language.

People use #!/bin/sh when they only use a limited set of features (defined by the POSIX standard) for maximum portability. #!/bin/bash is perfectly fine for user scripts that take advantage of useful bash extensions.

/bin/sh is usually symlinked to either a minimal POSIX compliant shell or to a standard shell (e.g. bash). Even in the latter case, #!/bin/sh may fail because bash will run in compatibility mode as explained in the man page:

If bash is invoked with the name sh, it tries to mimic the startup behavior of historical versions of sh as closely as possible, while conforming to the POSIX standard as well.

The meaning of sh myscript.sh

The shebang is only used when you run ./myscript.sh, /path/to/myscript.sh, or when you drop the extension, put the script in a directory in your $PATH, and just run myscript.

If you explicitly specify an interpreter, that interpreter will be used. sh myscript.sh will force it to run with sh, no matter what the shebang says. This is why changing the shebang is not enough by itself.

You should always run the script with its preferred interpreter, so prefer ./myscript.sh or similar whenever you execute any script.

Other suggested changes to your script:

  • It is considered good practice to quote variables ("$i" instead of $i). Quoted variables will prevent problems if the stored file name contains white space characters.
  • I like that you use advanced parameter expansion. I suggest to use "${i%.mp4}.mp3" (instead of "${i/.mp4/.mp3}"), since ${parameter%word} only substitutes at the end (for example a file named foo.mp4.backup).


Related Topics



Leave a reply



Submit