How to have a Gradle task set shell set environment variables? - gradle

I have a Gradle task which invokes a shell script which sets some environment variables. These variables are used by another shell script which is also invoked by Gradle as another task. However, the second task cannot view these variables. What is wrong and how do I actually achieve my required behavior?
I am working in Unix/Linux. Both the Gradle tasks are basically Exec type of tasks.
Assuming, I am ready to out source the work done by the first shell script (setting env variables) to Gradle. How can I make the second shell script pick up these variables?

Are you exporting environ variables you want to share? Try with export keyword, as suggested in the following example:
$ cat a.sh
#! /bin/sh
export VAR=val
/path/to/b.sh
$ cat b.sh
#! /bin/sh
echo $VAR
When you execute a.sh the output "val" is printed on the screen.
Hope this helps! :)

Related

Edit enviroment variables inside python for script bash

my project, which uses mapreduce without hadoop, is composed of two files:
bash.sh and mapreduce.py.
I would like to use environment variables to communicate the information between bash.sh and mapreduce.py.
Within bash.sh I use export myvariable and on mapreduce.py, I use os.environ ['myvariable'].
I would like to edit myvariable within mapreduce.py and print the result via bash.sh. I tried to execute this istruction: os.environ ['myvariable'] = 'hello', but on bash.sh 'myvariable' is empty. Do you have any suggestions?
You can't do it from python, but some clever bash tricks can do
something similar. The basic reasoning is this: environment variables
exist in a per-process memory space. When a new process is created
with fork() it inherits its parent's environment variables. When you
set an environment variable in your shell (e.g. bash) like this:
/why-cant-environmental-variables-set-in-python-persist
So you can only make available to Bash script if the bash script is called inside python process space. A simple example can be
bash script
#!/bin/bash
echo "var from python is $myvariable"
python script
import os
os.environ ['myvariable'] = 'hello'
print(os.environ['myvariable'])
# all environment varaibles will be availbe to bash script in this case
os.system('sh ./ab.sh')
This is the way that you can try. Otherwise, no way to set it and make it available to bash script.
Setting an environment variable sets it only for the current process
and any child processes it launches. So using os.system will set it
only for the shell that is running to execute the command you
provided. When that command finishes, the shell goes away, and so does
the environment variable. Setting it using os.putenv or os.environ has
a similar effect; the environment variables are set for the Python
process and any children of it.
ENV via python
You can also try vice versa as you mention in question
Here is sequence
First set in bash script
call python script from bash ( based on argument to avoid loop)
update ENV in python
call bash again from python, if you call outside it will vanish.
bash script
#!/bin/bash
export myvariable="hellobash"
echo "myvariable form bash $myvariable"
if [ ! -z $1 ]; then
./py.py
else
echo "myvariable after updated from python $myvariable"
fi
Call bash script outside from python with the argument like myscript.sh bash, without argument in python myscript.sh
#!/usr/bin/python
import os
print("myvar form python",os.environ['myvariable'])
os.environ ['myvariable'] = 'hello'
print("myvar form python after update",os.environ['myvariable'])
os.system('sh ./ab.sh')

How to pass output of one command as env variables to another

I have a bash script that when ran, produces output like this:
VAR1=test
VAR2=test
I want to pass these variables as environment variables to an npm script, which in this case is just running mocha in the current directory, like if I was running VAR1=test VAR2=test mocha.
Thanks in advance.
It's not a great design for a bash script to output shell variable assignments like that, but you can work around it with a wrapper script runwithvars:
#!/bin/bash
set -a # Auto-export all new variables
eval "$(mybashscript)" # Perform whichever actions the script outputs
exec "$#" # Execute the specified command
Now you can use runwithvars mocha to run mocha with those variables.
Note that if the script outputs key-value pairs instead of shell variable assignments, e.g. VAR1=some value with spaces instead of VAR1='some value with spaces', then this answer does not apply and could be fragile or dangerous.
Use export:
export VAR1=test
export VAR2=test

Set env variable from BASH script

I need make something like
$ source /etc/environments # called in bash.sh script
Of course after script finished no changes apply to shell.
I know this is tricky if because child process cant modify parent 'bash' process. But May be another way to do so?
You should use
source bash.sh
Then it runs in the original shell instead of a child process.
As you have observed yourself a child process cannot set persistent environment variables. One of the usual work around are writing something like this to stdout:
% cat my_script
#!/bin/bash
echo "export MY_VAR=1234"
And then used in a command substitution:
eval "$(./my_script)"
An example of such script is dircolors

How to export or set a make variable from a shell file

I am running a shell script from make environment
I execute the script with input parameters as make variables:
/shell_script.sh $(make_var1) $(make_var2)
I process these variables in shell. I want to assign the result from a shell command to the make variable and export back to shell.
make_var=shell_command
How can I do this?
It is not trivial to change the parent environment of a shell-script, one approach is to echo the export statements and source the output of the script in your parent environment:
...
echo "export make_var1=${make_var1}"
...
and when you launch your script do it using eval:
eval $(./shell_script.sh $make_var1 $make_var2)
this is the approach taken by for example ssh-agent.
A second option is to source the script, in that case the script will be run line-by-line in the current shell:
. shell-script.sh
any export statements in the script will be run in the current shell.

Defining common variables across multiple scripts?

I have a number of Bash and Perl scripts which are unrelated in functionality, but are related in that they work within the same project.
The fact that they work in the same project means that I commonly specify the same directories, the same project specific commands, the same keywords at the top of every script.
Currently, this has not bitten me, but I understand that it would be easier to have all of these values in one place, then if something changes I can change a value once and have the various scripts pick up on those changes.
The question is - how is best to declare these values? A single Perl script that is 'required' in each script would require less changes to the Perl scripts, though doesn't provide a solution to the Bash script. A configuration file using a "key=value" format would perhaps be more universal, but requires each script to parse the configuration and has the potential to introduce issues. Is there a better alternative? Using environmental variables? Or a Bash specific way that Perl can easily execute and interpret?
When you run a shell script, it's done in a sub-shell so it cannot affect the parent shell's environment. So when you declare a variable as key=value its scope is limited to the sub-shell context. You want to source the script by doing:
. ./myscript.sh
This executes it in the context of the current shell, not as a sub shell.
From the bash man page:
. filename [arguments]
source filename [arguments]
Read and execute commands from filename in the current shell environment and return the exit status of the last command executed from filename.
If filename does not contain a slash, file names in PATH are used to find the directory containing filename.
Also you can use the export command to create a global environment variable. export governs which variables will be available to new processes, so if you say
FOO=1
export BAR=2
./myscript2.sh
then $BAR will be available in the environment of myscript2.sh, but $FOO will not.
Define environments variables :
user level : in your ~/.profile or ~/.bash_profile or ~/.bash_login or ~/.bashrc
system level : in /etc/profile or /etc/bash.bashrc or /etc/environment
For example add tow lines foreach variable :
FOO=myvalue
export FOO
To read this variable in bash script :
#! /bin/bash
echo $FOO
in perl script :
#! /bin/perl
print $ENV{'FOO'};
You could also source another file, so you do not create extra env variables, that may lead to unexpected behaviours.
source_of_truth.sh:
FOO="bar"
scritp1.sh
#!/usr/bin/env bash
source source_of_truth.sh
echo ${FOO}
# ... doing something
scritp2.sh
#!/usr/bin/env bash
source source_of_truth.sh
echo ${FOO}
# ... doing something else

Resources