environmental variable not available for next command in shell script [duplicate] - linux

This question already has answers here:
Shell script to set environment variables
(5 answers)
Closed 6 years ago.
We have a shell script named source.sh that exports many ENV variables required for a build.
I am trying to access those ENV variables by running source.sh in my script, but even after running that I am not able to access ENV variables for the succeeding commands.
My Script look alike:
#!/bin/bash
sh source.sh
cd $ROOT_VOS
make
But here cd $ROOT_VOSis not happening

sh source.sh
...runs source.sh in a separate copy of sh (actually, since your parent shell is bash and the child is sh, it's not just a "separate copy", it's an entirely different interpreter). When that separate interpreter exits, local variables and other changes to process-local state are gone. (Environment variables are inherited by child processes; they aren't propagated up the tree to parents).
Instead, use:
# POSIX-compliant: execute every command in source.sh in the current shell
. source.sh
...or...
# bash-specific, perhaps more-readable, synonym for the same
source source.sh

Related

Exported variables not available [duplicate]

This question already has answers here:
Setting console env using a shell script
(1 answer)
Defining a variable with or without export
(15 answers)
Closed 9 months ago.
I am working on automating some existing processes through linux shell scripts. What I want to do is run a script remotely through SSH that will then complete a number of tasks on the remote host.
The current file structure is like this:
setup.sh -> exports a list of environment variables
automate.sh -> executes setup.sh then runs automation
Let's say setup.sh does "export VAR=/test" and at the end of the automate.sh script I put the following line "env | grep VAR".
After unsetting VAR and then executing automate.sh, the variable does not get output, meaning it is empty.
Setting the environment variables in .profile or .bashrc will not work for me as setup.sh dynamically sets environment variables based on my parameters (For example, executing code from different regions requires different variables to be set, but all variables have the same name so the same code can be used for all regions).
I am assuming the problem here comes from automation.sh creating a new shell, then setup.sh creating a new child shell, meaning that the exported variables are not available in automation.sh
Can anyone with more experience tell me if this is likely the case? Or how I would verify if this is the case or not? Any suggested solutions would be welcome too.
Thanks.
Update: A suggested solution was to source setup.sh instead of executing it. This solves the problem. However, it would then mean I would need to source setup.sh in multiple places as other scripts will be executed later after automation.sh has complete.
Is there any way to run setup.sh and have the exported variables available to all following scripts?

Defining shell environment variables in tcsh [duplicate]

This question already has answers here:
Can a shell script set environment variables of the calling shell? [duplicate]
(20 answers)
Closed 3 years ago.
Unable to create environment variables using a tcsh script.
Tried set, but works only inside the script.
setenv doesn't work outside the script.
export says "command not found" in the terminal I'm trying to run.
#!/usr/intel/bin/tcsh
#set WV "/p/hdk/cad/custom_waveview/O-2018.09-SP2/bin/wv"
setenv WV "/p/hdk/cad/custom_waveview/O-2018.09-SP2/bin/wv"
echo $WV
env $WV "/p/hdk/cad/custom_waveview/O-2018.09-SP2/bin/wv"
I expect the output to be /p/hdk/cad/custom_waveview/O-2018.09-SP2/bin/wv, when i echo the environment variable WV on the terminal, but i am getting the error of undefined variable.
Environment variables are set in the current process and inherited by child processes. You can't set environment variables in a parent process.
You have to use the source command to execute the script. That makes the current shell process execute the script itself, rather than running it in a child process.
source env_vars.tcsh
set is for setting shell variables, not environment variables. export is a bash command (and also other shells based on Bourne Shell syntax), not a tcsh command.
env requires the arguments before the program name to be variable settings in the form name=value, e.g.
env VAR1=val1 VAR2=val2 /p/hdk/cad/custom_waveview/O-2018.09-SP2/bin/wv
It runs the program with those variables added to the environment.

Setting console env using a shell script

I have a shell script setmyenv.sh as below
#!/bin/sh
export PATH=./abc/tools:$PATH
env | grep PATH
When I run it sh setmyenv.sh, I could see that the PATH env is set accordingly.
PATH=./abc/tools:<whatever my existing PATH setting>
However, after my command finish, if I manually type env | grep PATH on the console, I got
PATH=<whatever my existing PATH setting>
I lost the setting that I set using setmyenv.sh
It looks like the environement is only set in the lifetime of my script run.
How could I have the environment set sticky even after the script ended. i.e. the purpose of the script is to set the environment.?
P/S: I don't want to set it in my .bash_profile nor etc\profile, given I only want to set it when needed, by calling setmyenv.sh, but not every time I open my console. i.e. not per the answer of Using .sh script to set an environment variable or How to set global environment variables using shell script .sh
When you run
sh setmyenv.sh
it runs in a separate sh process and the changes to PATH are lost when the process finishes.
You need to source your script:
source setmyenv.sh
or
. setmyenv.sh
so that it runs in your current shell and all variable assignments are preserved. Remember not to have any exit in setmyenv.sh script. If you do, sourcing the script will terminate your shell.
See also:
Difference between sourcing a script vs executing it
What's a subshell

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.

incrementing an environmental variable

I need to increment an environmental variable by these steps:
envar=1
export envar
sh script_incrementation
echo $envar
where script_incrementation contains something like this:
#! /bin/sh
envar=$[envar+1] #I've tried also other methods of incrementation
export envar
Whatever I do, after exiting the script the variable remains with its initial value 1.
THanks for your time.
A shell script executes in its own shell, so you cannot affect the outer shell unless you source it. See this question for details of that discussion.
Consider the following script, which I will call Foo.sh.
#!/bin/bash
export HELLO=$(($HELLO+1))
Suppose in the outer shell, I define an environmental variable:
export HELLO=1
If I run the script like this, it run inside its own shell and will not affect the parent.
./Foo.sh
However, if I source it, it will just execute the commands in the current shell, and will achieve the desired affect.
. Foo.sh
echo $HELLO # prints 2
Your script can not change the environment of the calling process (shell), it merely inherits it.
So, if you export foo=bar, and then invoke sh (a new process) with your script, the script will see the value of $foo (which is "bar"), and it will be able to change its own copy of it – but that is not going to affect the environment of the parent process (where you exported the variable).
You can simply source your script in the original shell, i.e. run
source increment_script.sh
or
. increment_script.sh
and that will then change the value of the variable.
This is because sourceing a script avoids spawning a new shell (process).
Another trick is to have your script output the changed environment, and then eval that output, for example:
counter=$[counter+1]
echo "counter=$counter"
and then run that as
eval `increment_script.sh`

Resources