Shell script is unable to read groovy variable, tried multiple ways - shell

I am new to shell and groovy and I have already googled and read solutions below, but none of it seems to be working
Groovy parameter to shell script
Pass groovy variable to shell script
read file to variable shell script
How to pass a groovy variable to a shell block jenkins
How to pass groovy variable to shell script in Jenkinsfile?
Issue:
I want to read value from the groovy variable and pass it to shell script but either I get blank value or the literal variable name
Below is my code:
def Tenant_Instances = ''
//some more declarations and code
if(tenant_created)
{
Tenant_Instances = "author.${ciTenant}.rally-dev.com,publish.${ciTenant}.rally-dev.com"
println("tenant instance are -"+Tenant_Instances) //value coming fine here
//some code here
println("tenant instance again are -"+Tenant_Instances) //values coming fine here too
sh '''#!/bin/bash
echo "[MNR] - Beginning deployment of bundle(s) to AEM Package Manager"
IFS="," read -ra INSTANCES <<< $Tenant_Instances
echo "demo ${INSTANCES}" -->here value does not come properly
I have tried replacing Tenant_Instances with 'Tenant_Instances' or "${Tenant_Instances}" or $Tenant_Instances or '$Tenant_Instances'... but none of it seem to work.

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')

Passing variables in a YAML file to shell script

I have the following YAML file to store all the variables I use for the shell script. How do I pass one of the variable to the shell script? Please provide an example if possible.
testme:
Numberofservers: 3
EC2InstanceType: m4.2xlarge
DetailedMonitoring: 'true'
TerminationProtection: 'true'
DataEBSVolumeSize: 200
you can use this bash script https://gist.github.com/pkuczynski/8665367
to read your yaml and access the yaml property as bash variable

How to use Jenkins parameters in a shell script

I want to use the parameters that we define in the Jenkins job as arguments to the shell commands in the same job.
I have created a parameterized build with the following parameters:
high.version: 234
low.version: 220
I want to use these variables as arguments for the build's shell script:
/bin/bash /hai/mycode/scripts/run_script.sh high.version
How do I these parameters in the same job?
Jenkins will create environment variables with the parameters' names.
The caveat here is that Jenkins will also do that for parameters that do not represent valid variable names -- those are difficult to access in bash. This is the case in your example, as bash variable names must not contain the . character.
The easiest solution is that you
rename your parameters, e.g. to high_version and low_version (which are valid bash variable names)
then use the corresponding variable names when calling your script
Example:
/bin/bash /hai/mycode/scripts/run_script.sh "$high_version"
If you cannot rename parameters to represent valid bash variable names (e.g., for usability reasons: Jenkins presents variable names to end users in the Web form for starting a build): you can still access such parameters by grepping for the parameter name in the output of the env command.
What really helped me was Hudson: How to pass parameters to shell script
Solution: the variables are UPPERCASE even you define them in lowercase!
Use following syntax to pass jenkins parameter to shell script -
eg. YourScript.sh %JENKINS_PARAMETER%
after that in your script,you can use that parameter like normal shell script command line parameter.
eg. myParam = $1;
Have you try this?
echo "function hello() { " > gg.sh
echo "echo \$1">> gg.sh
echo "}" >> gg.sh
echo "hello \$1" >> gg.sh
chmod 777 gg.sh
./gg.sh $hello_version
Be careful of the variable name, dot is not that well supported, for detail, you can ref this.
https://issues.jenkins-ci.org/browse/JENKINS-7180
It is not a good practice to have dot(.) in your parameters. You should either choose highVersion OR high_version as your param names.
As per your question, it seems that you're working with a Freestyle job but many devs coming here would also be interested in the Pipeline syntax as well, so I'm giving a solution to use params in Jenkins pipeline DSL.
There are two ways you can use Jenkins parameters in the Jenkins Pipeline shell script -
As a Shell parameter
stage('Test'){
sh "/bin/bash /hai/mycode/scripts/run_script.sh $highVersion"
}
As a Groovy parameter
stage('Test'){
sh "/bin/bash /hai/mycode/scripts/run_script.sh ${params.highVersion}"
}
I would recommend to use a second method, as we're using groovy as a pipeline DSL.

jenkins - how to pass a value from bash to groovy?

I'm working on a jenkins install with two script components. The bash bits run first and then groovy. I'd like to be able to pass a value (property? Other?) from the bash script->groovy script.
Is this possible? Do I need to write the value to a property file and read it back in groovy?
EDIT: my goal from this was to generate a build # in bash and pass this to groovy so I could set the description and build # in the jenkins display. It appears that groovy isn't available on the build server so I'm looking for another direction. Currently experimenting with the 'postbuild' plugin and the 'env-inject' plugin. Open to suggestions.
Here are a few things to consider to make this successful:
Make sure you're trying to accomplish this with one "Execute shell" in Jenkins or from a script.
Export the shell variable so that the variable will be present in the child process that will execute your groovy script.
# foo.sh
export foo=bar
groovy myscript.groovy
# myscript.groovy
def env = System.getenv()
String myvar=env['foo']
println myvar
Running foo.sh should produce the following:
./foo.sh
bar
If for some reason you prefer not to export the variable (there may be good and valid reasons for this), you can still explicitly pass the variable to the groovy script as a "system property":
# foo.sh
foo=bar
groovy -Dfoo="$foo" yourscript.groovy
# yourscript.groovy
String yourvar = System.properties['foo']
println yourvar
which produces the following results:
$ ./foo.sh
bar
$
I just worked on this problem for days and thought I might share what I discovered. I had to access a variable in a groovy file from a .sh file and had difficulty at first grabbing the variable. There is a simple way to do it, though. Here's what I did:
In your bash file, save the value in a variable. Then in the groovy script, do this:
variableToGet = sh(returnStdout: true, script: """
. ${DIRECTORY}/bash_file.sh
echo \$VARIABLE
""").trim()
Hope this helps. This problem was a good challenge! It's important to note, however, that standard out will return a String, regardless of what type of variable you are grabbing. If you need to use an integer value, you can then use the integer value with Integer.parseInt(variableToGet)
The best way is setting an environment variable to share the information from bash into groovy. You could pipe things as well using standard in/out as well.
So if you are setting the env in a bash script it wont be available outside of that script. Instead of doing a bash script put the script inline in your command in jenkins. Run your bash code then call the groovy script.
Something like below
#do somebash scripting
VARIABLE="something"
#call your groovy code
groovy util.groovy
your groovy code (util.groovy):
String variable = env['VARIABLE']

Run external process from groovy

i have a bash script which i want to execute from groovy like
some_shell_script.sh param1 "report_date=`some_function 0 \"%Y%m%d\"`"
that script runs successfully from the command line, but when i try to execute it from Groovy
def command = "some_shell_script.sh param1 "report_date=`some_function 0 \"%Y%m%d_%H%M%S\"`""
def sout = new StringBuffer()
def serr = new StringBuffer()
//tried to use here different shells /bin/sh /bin/bash bash
ProcessBuilder pb = new ProcessBuilder(['sh', '-c',command])
Process proc = pb.start()
proc.consumeProcessOutput(sout, serr)
def status = proc.waitFor()
println 'sout: ' + sout
println 'serr: ' + serr
i have the following error
serr: sh: some_function: command not found
at the same time
which some_function
returns functional definition like
some_function ()
{
;some definition here
}
looks like when i run external script from groovy it start different process without context of parent process. I mean no function definitions of parent process are exists.
Anyone have cue how to cope with such a situation?
You should replace the double quotes in your command definition with single quotes.
def command = 'some_shell_script.sh param1 "report_date=`some_function 0 "%Y%m%d_%H%M%S"`'
Add:
println command
to ensure that you are executing the correct command.
Also open a new bash shell and ensure that some_function is defined.
Definitely check out those quotes as indicated by #Reimeus. I had some doubts about those.
In addition, some_function() may be defined in ~/.bashrc, /etc/bash.bashrc or in a file sourced by either of those when you run bash interactively. This does not happen if you run a script.
(Which is good for making script run predictably - you can't have your script depend on people's login environment.)
If this is the case, move some_function() to another file, and put its full path in the BASH_ENV variable, so that bash picks it up when processing scripts.
man bash:
When bash is started non-interactively, to run a shell script, for
example, it looks for the variable BASH_ENV in the environment, expands
its value if it appears there, and uses the expanded value as the name
of a file to read and execute. Bash behaves as if the following com-
mand were executed:
if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
but the value of the PATH variable is not used to search for the file
name.
[Manual page bash(1) line 158]
This seems a path problem. Can you put the full path to the script and try again?
DISCLAIMER: there are limitations with this solution, and, the shell sub-script commands should be properly tested before deployment. However if multithreading were not required e.g. the function provides immediately some short results, there is an alternative as I implemented in here.
For instance, if the result of mycmd depends on an environment variable set in ~/.bashrc I could display its result: (tried as a groovy-script/v1.8.1, and yes, this is a stupid example and it might be risky!)
commands = '''source ~/.bashrc; cd ~/mytest; ./mycmd'''
"bash".execute().with{
out << commands
out << ';exit $?\n'
waitFor()
[ok:!exitValue(), out:in.text, err:err.text]
}.with{ println ok?out:err }

Resources