I have a file run_me
#!/bin/bash
export BOBO=MOMO
After I run run_me, the variable BOBO isn't set. Why? How can it be fixed?
You need to source it:
. ./run_me
OR
source ./run_me
In order to run this script in current shell otherwise BASH creates a new sub-shell and executes the script in that sub-shell therefore all the changes (variable etc) are not reflected in the current parent shell.
Related
I have a bash script that is saved in a location included in my PATH variable. Within this script I need to source another script that is saved in a different location. In my first (main) script I change directory to the location of this second script and then I source it.
cd $path_of_2nd_script && source 2nd_script
The problem is that in my second script (the one that is sourced) I have some variables that need to retrieve the location of the second script with dirname $0. The problem is that is retrieving the location of the first script ($path_of_1st_script), not the $path_of_2nd_script where I changed directory in my main script, just before sourcing it. How can I pass the path_of_2nd_script into 2nd_script? Does it make sense?
Change source 2nd_script to e.g. bash 2nd_script. When using source, the argument will be executed in the current shell environment, which means that $0 will refer to the first script.
It is not clear why you are sourcing your second script rather than executing as a child process, in which case $0 would resolve to the name of the second script itself.
If you could change the second script to grab its directory from its $1 and then change the first script this way:
cd "$path_of_2nd_script" && source 2nd_script "$path_of_2nd_script"
I have a lot of bash scripts that work on an exported variable called WORKING_FILE.
This variable is exported in the main.sh script which is the first script launched in a shell and during his execution it calls other scripts (e. g. child.sh).
Actually, child.sh see the WORKING_FILE as a copy of the main.sh environment and if it tries to change the WORKING_FILE the value will be lost at the end of its execution.
So, the question is:
how can child.sh modify the value of WORKING_FILE and change the WORKING_FILE value also in the main.sh without using files?
Thanks. :)
If you export the variable and execute the child, then you cannot -- the child gets a copy of the variable, and any changes are not visible in the parent.
You can, however, source the script,
. ./child.sh
or
source child.sh
This will execute the child script in the same interpreter and any changes to the environment this script makes will be visible in your script.
I did the following from a bash shell.
export myPath="/home/user/dir"
Then I verified the value of this by 'echo'ing this value from both shell and a inside a bash script. Both worked fine.
Then I tried setting the value of this variable from inside a script like this.
myPath="/home/user/newdir"
and tried printing this variable from shell. I thought the variable will hold the updated value, but it was showing the old value.
How can I update the value from a script? I am looking to do it without using source if possible.
To make the variables persist after the script finishes, you have to run it using the source command:
When a script is run using source it runs within the existing shell, any variables created or modified by the script will remain available after the script completes. In contrast if the script is run just as filename, then a separate subshell (with a completely separate set of variables) would be spawned to run the script.
I have a simple bash script:
#!/bin/bash
JAVA_HOME=/usr
EC2_HOME=~/ec2-api
echo $EC2_HOME
export PATH=$PATH:$EC2_HOME/bin
I run the script like so
$ ./ec2
/Users/user/ec2-api
The script runs and produces the correct output.
However, when I now try to access the EC2_HOME variable, I get nothing out:
$ echo $EC2_HOME
I get a blank string back. What am I doing wrong?
Do either of the following instead:
source ec2
or
. ec2
(note the . notation is just a shortcut for source)
Explanation:
This is because ./ec2 actually spawns a subshell from your current shell to execute the script, and subshells cannot affect the environment of the parent shell from which it spawned.
Thus, EC2_HOME does get set to /Users/user/ec2-api correctly in the subshell (and similarly the PATH environment variable is updated and exported correctly in the subshell as well), but those changes won't propagate back to your parent shell.
Using source runs the script directly in the current shell without spawning a subshell, so the changes made will persist.
(A note on export: export is used to tell new shells spawned from the current shell to use the variables exported from the current shell. So for any variables you would only use in the current shell, they need not be exported.)
A shell script can never modify the environment of their parent.
To fix your problem, you can use the dot (.) command:
$ . ./ec2
and that should work. In cshell, it would be
% source ./ec2
To learn more about shells and scripts, my best resource is by far Unix power tools.
I have some proxy settings that I only occasionally want to turn on, so I don't want to put them in my ~/.bash_profile. I tried putting them directly in ~/bin/set_proxy_env.sh, adding ~/bin to my PATH, and chmod +xing the script but though the script runs, the variables don't stick in my shell. Does anyone know how to get them to stick around for the rest of the shell session?
Use one of:
source <file>
. <file>
In the script use
export varname=value
and also execute the script with:
source set_proxy_env.sh.
The export keyword ensures the variable is marked for automatic inclusion in the environment of subsequently executed commands. Using source to execute a script starts it with the present shell instead of launching a temporary one for the script.
Did you try this:
. ~/bin/set_proxy_env.sh
Running it by itself opens a separate subshell (I think) and sets the variable there. But then the binding is lost after exiting back into your shell. The dot at the front tells it to run it within the same shell.
Also, don't forget to export the variables you need like so: export MYVAR=value