What is the difference between ./a.sh and . ./a.sh? [duplicate] - linux

This question already has answers here:
What is the difference between "./somescript.sh" and ". ./somescript.sh"
(4 answers)
Closed 8 years ago.
What I know is when I am having two script files lets say a.sh and b.sh and to use the variable or function defined in script a.sh, then . ./a.sh works but ./a.sh doesn't works. While running a shell script both ./script.sh and . ./script.sh works fine. What is the difference between running a script with ./script.sh and . ./script.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.

The notation . ./a.sh is short for source ./a.sh. source is a built-in command of the executing shell to read the given file line-by-line and execute all that is written there as if it was typed in the shell directly. As a consequence, if there is an exit statement in a.sh, it will close the shell which sources this; typically, the xterm window closes then.
The notation ./a.sh, however, starts a new process; this is done by the current shell forking itself and then making the forked child executing the given program. This is, in this case, a shell script again, so a new shell will be executed. Everything this new shell does will not influence the original (parent) shell. If the child is not sent to the background, the parent then waits for the child to terminate.

Related

How does a subshell's executed lines get printed to the main shell without running the source command?

Let's say I have an executable shell script called foo.sh. Inside it is a simple echo "Hello World". From my understanding, when I run this via ./foo.sh, a subshell is invoked which executes the echo "Hello World" line.
Why, then, do I see the output of the echo command in my main shell/terminal? I would think you'd have to do a "source ./foo.sh" instead of the simple "./foo.sh" to see the output in your current shell.
Can any of you help clarify?
The standard output is inherited. Quoting from Bash Reference Manual:
Command Execution Environment
When a simple command other than a builtin or shell function is to be
executed, it is invoked in a separate execution environment that
consists of the following. Unless otherwise noted, the values are
inherited from the shell.
the shell’s open files, plus any modifications and additions specified by redirections to the command
...

clarification about bash script [duplicate]

This question already has answers here:
Why can't I change directories using "cd" in a script?
(33 answers)
Closed 6 years ago.
I am new to bash scripting. This might be obvious to many. please bear with me.
I have a shell script as follows:
#!/bin/bash
echo `pwd`
cd /home/foo/bar
echo `pwd`
Let's say I am currently in dir : /home/foo1
If I execute the above script it prints:
/home/foo1
/home/foo/bar
But once the script completes execution, I have seen that it still remains in dir /home/foo1
I have also seen some scripts where there are explicit commands to reset the working dir using 'cd -' command.
If bash executes all the lines in the script as commands, why does it again reset the working dir?
When you are running an interactive session of bash, and from it, you execute a script (e.g. ./myscript.sh), then bash creates a new bash process to execute the script. Initially, that process get copy of the same environment as the original process (e.g. the current working directory, or environment variables), but if the script modifies the environment somehow, this changes only affect the new process, not the original one. So when the scripts exits, you go back to the original process which retains the original environment. So it is not possible to modify the current directory of the original shell from a script.
As a side note, the following line
echo `pwd`
does not make much sense. You either have to do echo $PWD or simply pwd.

Changing bash prompt temporarily by own script [duplicate]

This question already has answers here:
Changing PS1 prompt in a Bash parent shell
(3 answers)
Closed 6 years ago.
I wanted to write a tiny shell script that shortens the commmand prompt when it gets too long. Setting the PS1 variable in bash works fine. When I try the same command directly in a script and run it, nothing happens.
#!/bin/bash
PS1='\u:\W\$ '
I tried eval "PS1='\u:\W\$ '" , export PS1='\u:\W\$ ' and exec PS1='\u:\W\$ ' without any result.
How can I achieve the same result as a direct input in the bash?
Thank you in advance
In general, in UNIX, a process can only change variables for itself and its children -- not its parent ("its parent" being the process that invoked it).
You need to source a script, not execute it, for it to be able to effect your interactive shell's variables. This executes all commands inside the script inside your current shell, not a new shell started as a child process (whose variables' values are thrown away on exit).
# in bash
source yourscript
# or in POSIX sh
. yourscript # mind the space!
In this usage, the shebang does nothing; similarly, the +x permission isn't needed either. It's also typical to name scripts intended to be sourced rather than executed with an extension mapping to the shell they're intended to be used by (yourscript.bash for bash, yourscript.sh for a script which can be sourced by any POSIX shell), whereas scripts intended to be executed rather than sourced should have no extension.

Difference between different ways of running shell script

Recently I have been asked a question. What are the different ways of executing shell script and what is the difference between each methods ?
I said we can run shell script in the following methods assuming test.sh is the script name,
sh test.sh
./test.sh
. ./test.sh
I don't know the difference between 1 & 2. But usually in first 2 methods, upon executing, it will spawn new process and run the same. Whereas in the last method, it won't spawn new process. Instead it runs in the same one.
Can someone throw more insight on this and correct me if I am wrong?
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 occurs when a file is `source`-d in Unix/Linux context?

I've seen shell scripts that include a line such as:
source someOtherFile
I know that causes the content of someOtherFile to execute, but what is the significance of source?
Follow-up questions: Can ANY script be sourced, or only certain type of scripts? Are there any side-effects other than environment variables when a script is sourced (as opposed to normally executing it)?
Running the command source on a script executes the script within the context of the current process. This means that environment variables set by the script remain available after it's finished running. This is in contrast to running a script normally, in which case environment variables set within the newly-spawned process will be lost once the script exits.
You can source any runnable shell script. The end effect will be the same as if you had typed the commands in the script into your terminal. For example, if the script changes directories, when it finishes running, your current working directory will have changed.
If you tell the shell, e.g. bash, to read a file and execute the commands in the file, it's called sourcing. The main point is, the current process (shell) does this, not a new child process.
In BASH you can use the source command or simply . to source a file.
source is a Unix command that evaluates the file following the command, as a list of commands, executed in the current context. You can also use . for sourcing the file.
source my-script.sh;
. my-script.sh;
Both commands will have the same effect.
In contrast, passing the script filename to the desired shell will run the script in a subshell, not the current context.

Resources