Difference between executing a script with 'bash cd.sh' and 'source cd.sh'? [duplicate] - linux

This question already has answers here:
What is the difference between using `sh` and `source`?
(5 answers)
Closed 7 years ago.
Explain the difference between executing a script with bash cd.sh and source cd.sh
cd.sh contains:
#!/bin/sh
cd /tmp

bash execute the script in a child shell that cannot modify the environment of the invoking shell while source executes the script in the current shell:
test.sh
#!/bin/sh
export MY_NAME=chucksmash
echo $MY_NAME
Running test.sh:
chuck#precision:~$ bash test.sh
chucksmash
chuck#precision:~$ echo $MY_NAME
chuck#precision:~$ source test.sh
chucksmash
chuck#precision:~$ echo $MY_NAME
chucksmash
chuck#precision:~$

In bash, commands that look like source script.sh (or . script.sh) run the script in the current shell, regardless of the #! line.
Therefore, if you have a script (named script.sh in this example):
#!/bin/bash
VALUE=1
cd /tmp
This would print nothing (because VALUE is null) and not change your directory (because the commands were executed in another instance of bash):
bash script.sh
echo $VALUE
This would print 1 and change your directory to /tmp:
source script.sh
echo $VALUE
If you instead had this script (named script.py in this example):
#!/usr/bin/env python
print 'Hello, world"
This would give a WEIRD bash error (because it tries to interpret it as a bash script):
source shell.py
This would *also *give a WEIRD bash error (because it tries to interpret it as a bash script):
bash shell.py
This would print Hello, world:
./shell.py # assuming the execute bit it set

Related

Bash: Creating a shell variable in a bash script that I can access from command line

I have very little experience working with bash. With that being said I need to create a bash script that takes your current directory path and saves it to a shell variable. I then need to be able to type "echo $shellvariable" and have that output the directory that I saved to that variable in the bash script. This is what I have so far.
#!/bin/bash
mypath=$(pwd)
cd $1
echo $mypath
exec bash
now when I go to command line and type "echo $mypath" it outputs nothing.
You can just run source <file_with_your_vars>, this will load your variables in yours script or command line session.
> cat source_vars.sh
my_var="value_of_my_var"
> echo $my_var
> source source_vars.sh
> echo $my_var
value_of_my_var
You have to export the variable for it to exist in the newly-execed shell:
#!/bin/bash
export mypath=$(pwd)
cd $1
echo $mypath
exec bash
Hello
'env -i' gives control what vars a shell/programm get...
#!/bin/bash
mypath=$(pwd)
cd $1
echo $mypath
env -i mypath=${mypath} exec bash
...i.e. with minimal environment.

How to execute commands read from the txt file using shell? [duplicate]

This question already has answers here:
Run bash commands from txt file
(4 answers)
Closed 4 years ago.
I tried to execute commands read it from txt file. But only 1st command is executing, after that script is terminated. My script file name is shellEx.sh is follows:
echo "pwd" > temp.txt
echo "ls" >> temp.txt
exec < temp.txt
while read line
do
exec $line
done
echo "printed"
if I keep echo in the place of exec, just it prints both pwd and ls. But i want to execute pwd and ls one by one.
o/p am getting is:
$ bash shellEx.sh
/c/Users/Aditya Gudipati/Desktop
But after pwd, ls also need to execute for me.
Anyone can please give better solution for this?
exec in bash is meant in the Unix sense where it means "stop running this program and start running another instead". This is why your script exits.
If you want to execute line as a shell command, you can use:
line="find . | wc -l"
eval "$line"
($line by itself will not allow using pipes, quotes, expansions or other shell syntax)
To execute the entire file including multiline commands, use one of:
source ./myfile # keep variables, allow exiting script
bash myfile # discard variables, limit exit to myfile
A file with one valid command per line is itself a shell script. Just use the . command to execute it in the current shell.
$ echo "pwd" > temp.txt
$ echo "ls" >> temp.txt
$ . temp.txt

Linux bash know the script path which includes library script [duplicate]

This question already has answers here:
How do I know the script file name in a Bash script?
(25 answers)
Closed 7 years ago.
I have a library script named A and a script B, C which includes A with
. ../../../A
The problem is how A can know which time I run ./B.sh or ./C.sh, example:
if(run ./B.sh)
echo "B (file path) is calling"
else
echo "C (file path) is calling"
You can use $0 to determine the command that was executed:
A.sh:
echo $0
B.sh:
. ./A.sh
When run:
$ sh B.sh
B.sh
$ sh A.sh
A.sh
It will only give the command that was executed, not the arguments:
$ sh B.sh one two three
B.sh

Piping a shell script to bash and launch interactive bash

Consider the following shell script on example.com
#/bin/bash
export HELLO_SCOPE=WORLD
eval $#
Now, I would like to download and then execute this shell script with parameters in the simplest way and be able to launch an interactive bash terminal with the HELLO_SCOPE variable set.
I have tried
curl http://example.com/hello_scope.sh | bash -s bash -i
But it quits the shell immediately. From what I can understand, it's because curls stdout, the script, remains the stdin of the bash, preventing it from starting interactively (as that would require my keyboard to be stdin).
Is there a way to avoid this without going through the extra step of creating a temporary file with the shell script?
You can source it:
# open a shell
. <(curl http://example.com/hello_scope.sh)
# type commands ...
You could just download this script you (using wget for example) and source this script, isn't it ?
script_name="hello_scope.sh"
[[ -f $script_name ]] && rm -rf "$script_name"
wget "http://example.com/$script_name" -O "$script_name" -o /dev/null
&& chmod u+x "$script_name"
&& source "$script_name"
You could use . "$script_name" instead of source "$script_name" if you want (. is POSIX compliant). You could write the previous code in a script and source it to have interactive shell with the setted variable $HELLO_SCOPE.
Finally you could remove the eval line in your remote shell script.

Concatenate strings inside bash script (different behaviour from shell)

I'm trying some staff that is working perfectly when I write it in the regular shell, but when I include it in a bash script file, it doesn't.
First example:
m=`date +%m`
m_1=$((m-1))
echo $m_1
This gives me the value of the last month (actual minus one), but doesn't work if its executed from a script.
Second example:
m=6
m=$m"t"
echo m
This returns "6t" in the shell (concatenates $m with "t"), but just gives me "t" when executing from a script.
I assume all these may be answered easily by an experienced Linux user, but I'm just learning as I go.
Thanks in advance.
Re-check your syntax.
Your first code snippet works either from command line, from bash and from sh since your syntax is valid sh. In my opinion you probably have typos in your script file:
~$ m=`date +%m`; m_1=$((m-1)); echo $m_1
4
~$ cat > foo.sh
m=`date +%m`; m_1=$((m-1)); echo $m_1
^C
~$ bash foo.sh
4
~$ sh foo.sh
4
The same can apply to the other snippet with corrections:
~$ m=6; m=$m"t"; echo $m
6t
~$ cat > foo.sh
m=6; m=$m"t"; echo $m
^C
~$ bash foo.sh
6t
~$ sh foo.sh
6t
Make sure the first line of your script is
#!/bin/bash
rather than
#!/bin/sh
Bash will only enable its extended features if explicitly run as bash. If run as sh, it will operate in POSIX compatibility mode.
First of all, it works fine for me in a script, and on the terminal.
Second of all, your last line, echo m will just output "m". I think you meant "$m"..

Resources