Jenkins - Execute bash script to deploy application - bash

I have one bash script which deploys the application inside JBoss9.
It's working fine When I runs bash script from ubuntu terminal using command ./jbctl -c restart tail -f nohup.out;
But when I calls same bash script inside Jenkins - Build - Execute shell, it shows me various errors like
./jbctl: line 123: cat: command not found
./jbctl: line 123: grep: command not found
./jbctl: line 123: cut: command not found
./jbctl: line 123: sed: command not found
./jbctl: line 124: cat: command not found
/tmp/jenkins2547454576675677717.sh: line 10: tail: command not found
Build step 'Execute shell' marked build as failure
Finished: FAILURE
Without this jbctl.sh file, application can't be initialised. As there are bash commands inside this ./jbctl.sh file, these are not executed inside Jenkins - Build - Execute shell.
Is there any other way to run this jbctl.sh script inside Jenkins? Actually this is bash script.

There are two approaches to your issue:
Adjust Jenkins' environment variables (prefered) as e.g. described at wiki.jenkins.io. In short: Navigate to Manage Jenkins > Global Properties > Environment variables. For more, see also SO: "modify PATH variable in jenkins master"
Quick'n'dirty: Instead of cat use the full path of your command, e.g. /usr/bin/cat. You can determine this full path with entering which cat in your bash.

Related

How to source multiple scripts in different locations in jenkins

I need to source 2 scripts in different locations and then run docker-compose but I am facing error that the scripts must be sourced first.
I found this How to use source command within Jenkins pipeline script question and wrote my jenkins commnad as below:
. ../env/scriptA.sh arg-1 ../env/scriptB.sh ../compose/build.yml arg-2
But still facing that error. So how I can source all these scripts and build file in the jenkins?
from bash manual
. (a period)
. filename [arguments]
Read and execute commands ...
the syntax is one filename and then positional parameters, it can't accept multiple files.
Concatenating files doesn't allow to change paramters between calls, maybe a command sequence could be used if allowed
{ . file1 args ; . file2 args;}
Note the space after the first opening brace and semicolon before closing brace are important.
As Nahuel Fouilleul mentioned in his answer this is just one line and the script and yml files are other arguments and as I mentioned in the comment to Nahuel Fouilleul the problem is because of "[[" I can't source that script in shell environment of jenkins (even if the script has its own shebang) so I added the shebang to the shell block in jenkins as below and now it works.
sh '''#!/bin/bash -xe
. ../env/scriptA.sh arg-1 ../env/scriptB.sh ../compose/build.yml arg-2
echo "other commands"
'''

change Jenkins shell for only one pipeline

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.

Cannot access mvn command from bash script

I want to run the following script as:
bash ./scripts/startapp.sh
Here is the script:
#!/bin/bash
str=$HOSTNAME
PREV_IFS=$IFS
IFS=. components=(${str})
ORIGINAL_DIRECTORY=`pwd`
REP_DIRECTORY=$ORIGINAL_DIRECTORY/src/main/resources
for part in "${components[#]}"
do
PATH=$REP_DIRECTORY/"$part"
REP_DIRECTORY=$PATH
done
IFS=$PREV_IFS
CONFIG_PATH=$REP_DIRECTORY/application.yaml
# Below is the final command I want to run from the terminal
`SPRING_CONFIG_LOCATION=$CONFIG_PATH mvn spring-boot:run`
I am getting
mvn: command not found
Without starting the script, I can use mvn spring-boot:run without any problem.
Make sure you have defined:
M2_HOME pointing to the base directory of your Maven installation
PATH must include $M2_HOME/bin
In your script you're overwriting the value of PATH on every iteration. You should change it to:
PATH=$PATH:$REP_DIRECTORY/"$part"

bash in windows error?

I'm trying to execute a very simple script with cygwin, composed of:
#!/bin/bash\n
echo "hi"\n
with cygwinpath\bin\bash.exe /cygdrive/c/my_path/test.bash
but it says
/cygdrive/c/my_path/test.bash: line 1: #!/bin/bash: No such file or directory
However, it still prints 'hi'.
Why is this, and how to fix it ?
Thanks.
The first line of your script should just be #!/bin/bash and not #!/bin/bash\n
The code is still executing because the heading #!/bin/bash specifies a shell, and echo "hi"\n is a command to the terminal.
As for your issue I'm having no problems running it using the following path in the cygwin terminal:
/cygdrive/c/<my_path>/bin/bash.exe /home/user/test.bash

command errors in a file but runs fine on a shell

I am trying to run a command in a script, something like this one:
ssh user#host:/bin/echo > /home/path/file.log
Now when I run this command on a command line it works fine, however when put in a script (shell or ruby ) it cribs saying:
/bin/sh: /home/path/*.log: No such file or directory
Am I missing something?
Thanks!
Update:
It's weird that same thing is not being executed now even on the shell when I use putty. I have verified that the path and file exists on remote machine which is being ssh'ed into.
You need to loop over the files. If it works from the command line then your interactive shell is not a standard shell.
for f in /home/path/*.log; do
:>"$f"
done
Note also the use of a null command; in many shells, you don't need a command at all. Your echo puts an unattractive empty line at the beginning of each file.
If you are attempting to run this remotely, you will need to quote it:
ssh user#remote 'for f in /home/path/*.log; do :>"$f"; done'
Its working fine when I put quotes:
ssh user#host:"/bin/echo > /home/path/file.log"

Resources