How can I make Jenkins use Bash rather than its native shell for just one Jenkins pipeline/Jenkinsfile? Does the "agent" help me to do this?
I wrote a shell script for deployment but some of the parameters contain whitespace which messes up the resulting command I generate by losing some args. I've found how to avoid this problem by globally configuring Jenkins shell type to be Bash. But when I change the global shell type, my other Jenkins pipelines that use the Jenkins docker plugin syntax get broken when they use the 'sh' command within a docker container. My workaround is to ping pong the global setting for shell type depending on which Jenkins build I want to run. Its a royal PITA.
I'm embarrassed to say all I needed was a shebang.
My Jenkinsfile runs a custom (bash) shell script, using Jenkin's sh command, like in the following:
sh "./deploy.sh \"arg1\" \"arg 2\" \"arg3\""
In order to force deploy.sh to run within Bash, the contents of deploy.sh need to include #!/bin/bash on the first line, as in:
#!/bin/bash
echo "deploy args: $#"
Regardless, I think there should be a way to tell a Jenkins pipeline that it should run with specific settings, like sh=bash.
Related
So I have created a very simple Shell Script. All it does it set 3 ENV variables for AWS so that I can send a .csv file to S3 in a separate script.
#!/usr/bin/env bash
export AWS_DEFAULT_REGION=us-east-1
export AWS_SECRET_ACCESS_KEY=ksjdnkjsdnfkjsndfksjnfd
export AWS_ACCESS_KEY_ID=kjsdnfkjsndfkjsndfkjsdn
The SECRET KEY and KEY_ID have been changed for this post, just so we're clear
But for some reason, when I run this Shell Script, nothing seems to happen at all. When I run the ENV command, none of the variables are set. HOWEVER, when I copy and paste each command into my terminal individually, it sets the variable without issue. And then I am able to send my .csv file to S3 without issue.
I feel like I'm doing something extremely trivial that's causing the script to simply not run the commands.
Any ideas?
System: Raspberry Pi 3
Release: 10
-Joe
If you're just executing your script ./myscript.sh, the environment variables won't be set in your shell just the subshell it executes in.
You can execute your script with a "dot space script" syntax or use source. Both of which will execute the script in the current shell instead of launching a subshell.
. myscript.sh
source myscript.sh
Currently I have framework which is hosted in GitHub. Inside the framework (Maven) there is an shell .sch script which Jenkins will execute.
I know its possible to pass parameters from Jenkins (Via This project is parameterised option) but is there a way to pass run time parameters from Jenkins into an .SH script?
It should work just like passing any other value to a shell script.
sh '''
yourscript.sh ${PARAM1} ${PARAM2} ${PARAM3}
'''
im trying to get my server to execute a simple bash script:
#!/bin/bash
echo Hello World
After saving this to /var/www/script (im saving it to the web directory for no reason in particular) i try and execute it with
exec /var/www/script
This fails returning i don't have permission to execute it, sudo exec isn't a thing so i do sudo -i then run exec /var/www/script as root and i still have permission denied. I fairly uncertain why executing it as root doesn't work. Im wondering if i'm
A) using the wrong command to execute a bash script
B) have incorrect formatting in the script
C) shouldn't have saved it to /var/www/
D) done some other thing that i'm not even aware of.
Im running ubuntu server 16.04 if that helps.
File Permissions
First, make sure that you have the correct file permissions:
chmod +x /var/www/script_name #Gives the current user execute permissions
Executing Your Bash Script
In order to execute your bash script, the easiest option is to just simply call it (without any additional commands) by typing in the relative path to the script:
/var/www/script_name
There are other options for explicitly executing your script from the shell (in your case, use the bash shell to execute your script as a bash script). From TLDP documentation...
A script can also explicitly be executed by a given shell, but generally we only do this if we want to obtain special behavior, such as checking if the script works with another shell or printing traces for debugging:
rbash script_name.sh # Execute using the restricted bash shell
sh script_name.sh # Execute using the sh shell
bash -x script_name.sh # Execute using the bash shell
A Note on File Extensions: "Shebang" line > File extension
It is not an advised practice to use file extensions with your scripts, especially if you think your code may evolve beyond its current functionality.
Just in case you were wondering if the file extension may be your problem... it is not. It is important that you know that the file extension of a script isn't necessary at all. What matter is what you put in the "shebang" line:
To use the sh shell:
#!/bin/sh
To use the bash shell:
#!/bin/bash
It won't matter what file extension you use - the "shebang" line indicates what shell will be used to execute the script. You could save a script with the "shebang" of #!/bin/bash as script_name.py, but it would remain a bash script. If you attempt to execute it, ./script_name.py, it would be executed as a bash script.
As #Arjan mentioned in the comments, using file extensions for your script could lead to unnecessary complications if you decide to change the implementation of your project (i.e., a different shell / language):
I could decide later to shift my project to sh, python, perl, C, etc. Perhaps because I want to add functionality. Perhaps because I want to make it portable to a system without bash. It would be much more difficult if I used the .sh file extension, since then I'd need to change all my references to the script just because I changed its implementation.
You have two choices:
Run it as an argument to bash:
bash /var/www/script
Alternatively, set the execute bit:
chmod +x /var/www/script
And, now you can execute it directly:
/var/www/script
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 scriptlets written using the bash shell instead of the sh shell. During the build process I have warnings that indicate that I should be using sh instead of bash. Is there a parameter I can set to indicate that I am using bash instead of sh shell??
The rpm seems to install ok however but I wanted to know if I could specify bash somewhere?
thanks
Have you tried including a sh-bang line as the first line in the scriptlets in your spec file (like I just noticed the comment mentioned)
%post
#!/bin/bash
... rest of our post script here
If this works, you should also set up a scriptlet dependency like
Require(post): bash