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.
Related
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
I am using global variable as INSTALL_DIR='/tmp' and then am calling function to use that variable in shell script
Which is the correct method from the following to use the variable?
Method 1:-
INSTALL_DIR='/tmp'
install_app() {
echo "application path - $INSTALL_DIR"
}
install_app
Method 2:-
INSTALL_DIR='/tmp'
install_app() {
app=$1
echo "application path - $app"
}
install_app $INSTALL_DIR
If you want to use variable in multiple places with in same script, then first approach is better.
But if variable will be used in different scripts , then you have to Export it (export will make it environment variable) in first script before using in second script. Refer to this link for exporting from one script to other.
Pass all variables from one shellscript to another?
For different scripts, use extra one-dot (.) to run . ./myscript.sh, it will execute within same scope.
I'm running Fastlane (a continuous build tool for iOS) in order to execute a custom shell script for decrypting a file.
This is the command.
sh "./decrypt.sh ENV['ENCRYPTION_P12']"
I cannot figured out a way to pass the environment variable to that script. Obviously, if I hardcode the pwd into the script, it works correctly.
sh "./decrypt.sh mypwd"
Any suggestions?
Expanding From Within The Immediate Shell
Assuming that sh, here, is a fastlane command that invokes a shell command with the given argument as script text:
# as a fastlane directive
sh './decrypt.sh "$ENCRYPTION_P12"'
Note that if this were being literally invoked as a command line for /bin/sh, it would need a -c argument:
# in other contexts
sh -c './decrypt.sh "$ENCRYPTION_P12"'
Note that this absolutely depends on ENCRYPTION_P12 being an environment variable -- that is, exported to the environment by the system by which it was set.
Expanding from Within The Invoked Script
That said, if it is an environment variable, you have a better option: Just use it.
That is, inside decrypt.sh, you can refer to "$ENCRYPTION_P12" without needing to set it explicitly, as the shell implicitly imports all environment variables as shell variables -- and they're passed down to child processes without any explicit actions needed.
Things to Avoid: Shell Injection Attacks
Finally, an aside: The dangerous way to do this would have been something like:
# INSECURE: DO NOT DO THIS
sh "./decrypt.sh #{ENV['ENCRYPTION_P12']}"
or
# STILL INSECURE
sh "./decrypt.sh \"#{ENV['ENCRYPTION_P12'}\""
or
# STILL INSECURE
sh "./decrypt.sh '#{ENV['ENCRYPTION_P12'}'"
...thereby substituting the value into your generated string at the Ruby level. This is dangerous, however, as that string is parsed as code -- meaning that contents of ENCRYPTION_P12 could then be leveraged in shell attacks.
For instance, consider the case (given below in bash syntax):
# this will make any of the above do Very Evil Things
ENCRYPTION_P12=$'$(rm -rf ~)\'$(rm -rf ~)\''
...for which both rms will execute if directly substituted into generated shell script (as opposed to expanded during parameter expansion -- '${foo}' -- which takes place after the expansion phases which make this dangerous have already passed).
The fastlane specific answer is https://docs.fastlane.tools/advanced/#shell-values
or, from within your Fastfile:
decrypted = sh("./decrypt" ENV[ENCRYPTION_P12])
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']
i have unix shell script which is need to be run like below
test_sh XYZ=KLMN
the content of the script is
#!/bin/ksh
echo $XYZ
for using the value of XYZ i have do set -k before i run the script.
is there a way where i can do this without doint set -k before running the script. or is there something that i can do in the script where i can use value of the parameter given while running the script in the below way
test_sh XYZ=KLMN
i am using ksh.
Any help is appreciated.
How about running this?
XYZ=KLMN ./test_sh //running from directory where test_sh is
If your script needs no other arguments, a quick and dirty way do to it is to put
eval "$#"
at the start of your script. This will evaluate the command line arguments as shell commands. If those commands are to assign a shell/environment variable, then that's what it will do.
It's quick-and-dirty since anything could be put on the command line, causing problems from a syntax error to a bad security hole (if the script is trusted).
I'm not sure if "$#" means the same in ksh as it does in bash - using just $* (without quotes) would work too, but is even dirtier.
It looks like you are trying to use the environment variable "INSTANCE" in your script.
For that, the environment variable must be set in advance of executing your script. Using the "set" command sets exportable environment variables. Incidentally, my version of ksh dates from 1993 and the "-k" option was obsolete back then.
To set an environment variable so that it is exported into spawned shells, simply use the "export" command like so:
export INSTANCE='whatever you want to put here'
If you want to use a positional parameter for your script -- that is have the "KLMN" value accessed within your script, and assuming it is the first parameter, then you do the following in your script:
#!/bin/ksh
echo $1
You can also assign the positional parameter to a local variable for later use in your script like so:
#!/bin/ksh
param_one=$1
echo $param_one
You can call this with:
test_sh KLMN
Note that the spacing in the assignment is important -- do not use spaces.
I am tring this option
#!/bin/ksh
echo $1
awk '{FS="=";print $2}' $1
and on the command line
test_sh INSTANCE=LSN_MUM
but awk is failing.is there any problem over here?
Probably #!/bin/ksh -k will work (untested).