Difference Between Different Ways of Running Shell Script

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



Leave a reply



Submit