The following conditional works as expected when run from the bash command line on my Jenkins server:
if (($BRANCH_COUNT > 0)); then .....
But when running in the context of a Jenkins pipeline step (calling sh ''' .... '''), it writes an error and always evaluates to false. The error message (below) suggests maybe it's interpreting the value of $BRANCH_COUNT (in this case it is 1) as a command, which is then not found?
/var/jenkins/workspace/deploy-config-db-update#tmp/durable-baa54bb3/script.sh: 16:
/var/jenkins/workspace/deploy-config-db-update#tmp/durable-baa54bb3/script.sh: 1: not found
Is there something different about the bash environment when run by the Jenkins sh command? Some special escaping or quoting needed?
if you use sh'''...''', the pipeline script variable will not be expanded in your shell script. You need to use sh """..."""
Moving William Pursell's comment into an answer, because it solved the problem.
Using (()) is a bashism. Try if test "$BRANCH_COUNT" -gt 0; then ...
Related
My requirement is to run multiple shell scripts at a time.
After searching on Google could conclude that I can use "&" at the end of filename while triggering the run like:
sh file.sh &
the thing is I have for loop which generates the values and gives runtime parameters for the shell script:
sample code:
declare -a arr=("1" "2")
for ((i=0;i<${#arr[#]};++i));
do
sh fileto_run.sh ${arr[i]}
done
this successfully triggers the fileto_run.sh in parallel but it hangs there itself.. imagine I have echo statement in the script then the following is how the code hangs:
-bash-x.x$ 1
2
until I use ctrl+c the code execution wont exit.
I thought of using a break statement but that breaks the loop.
Am I doing wrong anywhere?
Please do correct me.
I have written the following code:
#!/bin/bash
#Simple array
array=(1 2 3 4 5)
echo ${array[*]}
And I am getting error:
array.sh: 3: array.sh: Syntax error: "(" unexpected
From what I came to know from Google, that this might be due to the fact that Ubuntu is now not taking "#!/bin/bash" by default... but then again I added the line but the error is still coming.
Also I have tried by executing bash array.sh but no luck! It prints blank.
My Ubuntu version is: Ubuntu 14.04
Given that script:
#!/bin/bash
#Simple array
array=(1 2 3 4 5)
echo ${array[*]}
and assuming:
It's in a file in your current directory named array.sh;
You've done chmod +x array.sh;
You have a sufficiently new version of bash installed in /bin/bash (you report that you have 4.3.8, which is certainly new enough); and
You execute it correctly
then that should work without any problem.
If you execute the script by typing
./array.sh
the system will pay attention to the #!/bin/bash line and execute the script using /bin/bash.
If you execute it by typing something like:
sh ./array.sh
then it will execute it using /bin/sh. On Ubuntu, /bin/sh is typically a symbolic link to /bin/dash, a Bourne-like shell that doesn't support arrays. That will give you exactly the error message that you report.
The shell used to execute a script is not affected by which shell you're currently using or by which shell is configured as your login shell in /etc/passwd or equivalent (unless you use the source or . command).
In your own answer, you say you fixed the problem by using chsh to change your default login shell to /bin/bash. That by itself should not have any effect. (And /bin/bash is the default login shell on Ubuntu anyway; had you changed it to something else previously?)
What must have happened is that you changed the command you use from sh ./array.sh to ./array.sh without realizing it.
Try running sh ./array.sh and see if you get the same error.
Instead of using sh to run the script,
try the following command:
bash ./array.sh
I solved the problem miraculously. In order to solve the issue, I found a link where it was described to be gone by using the following code. After executing them, the issue got resolved.
chsh -s /bin/bash adhikarisubir
grep ^adhikarisubir /etc/passwd
FYI, "adhikarisubir" is my username.
After executing these commands, bash array.sh produced the desired result.
I'm executing this code:
node('my_windows_slave') {
sh 'ls'
}
In my Windows slave I can properly execute sh command:
But the pipeline script can't run the .sh file:
[Pipeline] sh
[D:\workspace\sandbox_pipeline] Running shell script
sh: D:\workspace\sandbox_pipeline#tmp\durable-2d7dd2f8\script.sh: command not found
What I could notice is that this .sh file is not even created, once I tried with bat and worked fined.
Any clue what could be the problem?
[UPDATE]
Jenkins somehow can't create the SH temporary file. Already checked the log, permissions, everything that came to my mind.
I will leave my workaround as an answer for while before approve it once I'm still not 100% sure about the root cause and might someone else show up with a elegant solution...
def shell(command) {
return bat(returnStdout: true, script: "sh -x -c \"${command}\"").trim()
}
Attention
You still executing SH commands in a CMD, it means some %d for example can break your SH command.
Use the bat step instead of sh.
From Jenkins docs:
Windows-based systems should use the bat step for executing batch commands.
I've trouble setting an environment variable for a container in an Jenkins pipeline.
It seems, that "withEnv" does not work nicely with machines without bash.
Can you confirm that? I cannot find an official statement ;-)
When I run the following snippet on the Jenkins slave it works.
But when it is executed in a docker container without BASH "$test" isn't set.
withEnv(["test='asd'"]){
sh 'echo $test'
}
https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-withenv-code-set-environment-variables
If I'm not mistaken, I believe the variable is not set correctly.
Try this:
withEnv(["test=asd"]){
sh "echo \$test"
}
Within a Jenkins pipeline:
$var = Groovy parameter
\$var (within a sh closure) = Bash parameter
${var} = also refers to Groovy parameter
In order to insert a groovy variable into a bash variable:
sh ("VAR=${GROOVY_VAR}")
Using a bash variable inside a sh closure:
sh (" echo \$BASH_VAR")
We have to use single quote when using withEnv in Jenkins.
withEnv(['test=asd']){
sh "echo \$test"
}
Because, the variable expansion is being done by the Bourne shell, not Jenkins.
(Quoting from documentation)
Find more info here: https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/
I am writing a simple bash script (checkServs.sh) that will ssh into a list of servers and perform a health check on them.
I keep getting errors on the following line:
SERVERS=(blah1.example.com blah2.example.com blah3.example.com blah4.example.com)
Error is:
checkServs.sh: 3: checkServs.sh: Syntax error: "(" unexpected
I've checked online examples and this seems correct, isn't it? Thanks in advance!
I don't know about the syntax error, but this should work:
SERVERS="blah1.example.com blah2.example.com blah3.example.com blah4.example.com"
for server in $SERVERS
do
echo $server
done
EDIT: As noted by Jonathan Leffler in a comment, maybe you are not running the script with bash. Other shells, such as dash, may not recognize the array syntax. If that's the case, you can do:
SERVERS=(blah1.example.com blah2.example.com blah3.example.com blah4.example.com)
for i in $(seq 0 3)
do
echo ${SERVERS[$i]}
done
But if you just want to loop through the names and run an SSH command (ie if having an array won't provide useful functionality), the first method is more straightforward.
Your remote server probably calls a different shell when executing commands. Try to add bash -c to your arguments:
ssh user#server bash -c "<your commands>"
Or:
ssh user#server bash < yourscript.sh ## None in yourscript.sh must read input though.
An opening parenthesis starts a subshell, which is not a correct thing to have on the right side of an equals sign. It expects a string expression, not a command.
Quotation marks are used to keep a string expression together.