93

Inside a groovy script (for a jenkins pipeline): How can I run a bash command instead of a sh command?

I have tried the following:

Call "#!/bin/bash" inside the sh call:

stage('Setting the variables values') {
    steps {
         sh '''
            #!/bin/bash
            echo "hello world"
         '''
    }
}

Replace the sh call with a bash call:

stage('Setting the variables values') {
    steps {
         bash '''
            #!/bin/bash
            echo "hello world"
         '''
    }
}

Additional Info:

My command is more complex than a echo hello world.

Rene Knop
  • 1,788
  • 3
  • 15
  • 27
Yago Azedias
  • 4,480
  • 3
  • 17
  • 31
  • What is your question ? Please formulate your question clearly and provide the problems details you are facing. – deimus Jun 02 '17 at 13:46
  • I think we have the same problem. Even with the second example, it still executes with sh instead of bash. Is that what you are seeing? – Jake Jul 19 '17 at 01:51
  • Yes, it is! A create a solution adding a .bash file on my git repository, so i speak to Jenkins run it on a specific path inside of my project. – Yago Azedias Jul 19 '17 at 01:54
  • Please see my answer on this StackOverflow post: https://stackoverflow.com/a/57381691/10398126 – Quinn Vissak Aug 06 '19 at 18:08
  • Take a look at my answer to a similar question here: https://stackoverflow.com/a/57381691/10398126 – Quinn Vissak Aug 06 '19 at 18:21
  • Please see my answer to a similar question here: https://stackoverflow.com/a/57381691/10398126 – Quinn Vissak Aug 06 '19 at 18:26

8 Answers8

157

The Groovy script you provided is formatting the first line as a blank line in the resultant script. The shebang, telling the script to run with /bin/bash instead of /bin/sh, needs to be on the first line of the file or it will be ignored.

So instead, you should format your Groovy like this:

stage('Setting the variables values') {
    steps {
         sh '''#!/bin/bash
                 echo "hello world" 
         '''
    }
}

And it will execute with /bin/bash.

proski
  • 3,603
  • 27
  • 27
Jake
  • 1,887
  • 2
  • 14
  • 14
  • @Jake Any idea how you gen use a bash-specific script in a stage? This part works for me too, but when I try to trigger a bash script it does not work for me. – DenCowboy Nov 24 '17 at 12:48
  • 23
    `java.lang.NoSuchMethodError: No such DSL method 'bash' found among steps` – Marcello Romani Dec 18 '18 at 15:07
  • 1
    For multi-line scripts or those run multiple times, I would create a new bash script file (starting from #!/bin/bash), and simply run it with: chmod +x './script.sh' && sh './script.sh' – mirekphd Dec 13 '19 at 16:45
  • You can also just use newline in the same string: `sh '#!/bin/bash\n echo "$SHELL"'` – red888 Apr 07 '22 at 16:11
  • 1
    Alternatively, one can also get rid of the first blank line like so: `'''\ ` – IppX Jul 28 '22 at 15:21
19

According to this document, you should be able to do it like so:

node {
    sh "#!/bin/bash \n" + 
       "echo \"Hello from \$SHELL\""
}
Jacob
  • 890
  • 6
  • 16
  • The logo returns a error for the "+" WorkflowScript: 9: illegal string body character after dollar sign; solution: either escape a literal dollar sign "\$5" or bracket the value expression "${5}" @ line 9, column 68. 2c-437a-b8a2-db013fe42f62\"" + – Yago Azedias Jun 02 '17 at 18:23
  • Can you please post the script? From what you've pasted, it looks like there are two quotes before the `+`, which is wrong. – Jacob Jun 02 '17 at 18:56
  • Thank you @Jacob I was having the same problem and your comment helped me to solve those! – Anuradha Fernando Jan 19 '19 at 21:53
  • Don't use "\n" and "+", just use tripple quotes to do a multi-line string. – Isaac Freeman Aug 20 '19 at 18:57
13

For multi-line shell scripts or those run multiple times, I would create a new bash script file (starting from #!/bin/bash), and simply run it with sh from Jenkinsfile:

sh 'chmod +x ./script.sh'
sh './script.sh'
mirekphd
  • 4,799
  • 3
  • 38
  • 59
12

I'm sure that the above answers work perfectly. However, I had the difficulty of adding the double quotes as my bash lines where closer to 100. So, the following way helped me. (In a nutshell, no double quotes around each line of the shell)

Also, when I had "bash '''#!/bin/bash" within steps, I got the following error java.lang.NoSuchMethodError: No such DSL method '**bash**' found among steps

pipeline {
    agent none

    stages {

        stage ('Hello') {
            agent any

            steps {
                echo 'Hello, '

                sh '''#!/bin/bash

                    echo "Hello from bash"
                    echo "Who I'm $SHELL"
                '''
            }
        }
    }
}

The result of the above execution is

enter image description here

Santosh Kumar Arjunan
  • 3,600
  • 3
  • 23
  • 24
7

If you want to change your default shell to bash for all projects on Jenkins, you can do so in the Jenkins config through the web portal:

Manage Jenkins > Configure System (Skip this clicking if you want by just going to https://{YOUR_JENKINS_URL}/configure.)

Fill in the field marked 'Shell executable' with the value /bin/bash and click 'Save'.

JellicleCat
  • 28,480
  • 24
  • 109
  • 162
1

In my case, I had to execute a Shell script in bash via jenkinsfile. Here's what worked for me :

sh 'core_devops/automation/scripts/ecs_initialize.sh'

And the first line in the script had

#!/bin/bash

Damini Suthar
  • 1,470
  • 2
  • 14
  • 43
iArc13
  • 162
  • 8
0

The problem is indeed that the shebang is ignored if it doesn't start at the very beginning of the file.

As an alternative to mangling the formatting for Jenkinsfile readers, I've taken to using this:

sh label: 'Run fancy bash script',
   script: '''
       #!/usr/bin/env  bash

       echo "Hello ${SHELL}!"
   '''.stripIndent().stripLeading()

Note that stripIndent() is not strictly necessary for it to work, but Jenkins logs are a lot nicer with it.

Raphael
  • 9,779
  • 5
  • 63
  • 94
0

In my case event

sh '''#!/bin/bash
      echo "Hello ${SHELL}!"
'''

return "Hello /bin/sh"...

after some search I found "sh" was "dash" instead of bash on another terminal

Ubuntu22 :

jenkins@ubuntu22:~$ command -v sh
/usr/bin/sh
jenkins@ubuntu22:~$ ls -l /usr/bin/sh
lrwxrwxrwx 1 root root 4 Mar 23  2022 /usr/bin/sh -> dash
jenkins@ubuntu22:~$ command -v dash
/usr/bin/dash

on my old Red Hat 7.4 :

[jenkins@RH7.4 ~]$ command -v sh
/usr/bin/sh
[jenkins@RH7.4 ~]$ ls -l /usr/bin/sh
lrwxrwxrwx 1 root root 4 Sep  6  2018 /usr/bin/sh -> bash
[jenkins@RH7.4 ~]$ command -v bash
/usr/bin/bash
[jenkins@RH7.4 ~]$ ls -l /usr/bin/bash
-rwxr-xr-x 1 root root 960632 Aug  3  2017 /usr/bin/bash