Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-40734

Shell step cannot use environment variables that contain $$

    XMLWordPrintable

Details

    • Bug
    • Status: Resolved (View Workflow)
    • Minor
    • Resolution: Fixed
    • durable-task-plugin

    Description

      When I run a Jenkinsfile that has a sh step that uses an environment variable (such as a password) that has two $$ in a row, they get replaced with one $.

      Here's the steps to reproduce:
      1. Make a global credential id "foo", username "foo", password "bar$$baz"
      2. Use this Jenkinsfile:

      node('linux') {
          withCredentials([[$class: 'UsernamePasswordMultiBinding', credentialsId: 'foo', passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME']]) {            
              echo "Username: ${env.USERNAME}"
              echo "Password: ${env.PASSWORD}"
              sh 'echo Username: $USERNAME, Password: $PASSWORD'
          }
      }
      

      When the build runs, the echo steps properly echo the user/pass which are then masked. But the shell step doesn't mask the password, which is incorrect. It has lost a $

      [Pipeline] echo
      Username: ****
      [Pipeline] echo
      Password: ****
      [Pipeline] sh
      [s_example] Running shell script
      + echo Username: ****, Password: bar$baz
      Username: ****, Password: bar$baz
      

      Attachments

        Issue Links

          Activity

            ericson2314 John Ericson added a comment - - edited

            I'm not really sure what the answer is for dealing with passwords that look like they have bash variable expansion in them.

            Having withCredentials escape the username and password before sticking them in the environment variables should do the trick, right?

            ericson2314 John Ericson added a comment - - edited I'm not really sure what the answer is for dealing with passwords that look like they have bash variable expansion in them. Having withCredentials escape the username and password before sticking them in the environment variables should do the trick, right?
            b_dean Ben Dean added a comment -

            Yes, that would be answer for withCredentials. But it would make the pipelines behave a bit differently than the envinject and credentials-binding plugins which do not escape $ in passwords. Maybe they should be fixed too.

            b_dean Ben Dean added a comment - Yes, that would be answer for withCredentials . But it would make the pipelines behave a bit differently than the envinject and credentials-binding plugins which do not escape $ in passwords. Maybe they should be fixed too.
            jglick Jesse Glick added a comment -

            Freestyle projects may always have been broken in this respect, but not my problem. This was clearly a bug, and 1.13 fixes it. I am tracking other use cases in JENKINS-41339.

            jglick Jesse Glick added a comment - Freestyle projects may always have been broken in this respect, but not my problem. This was clearly a bug, and 1.13 fixes it. I am tracking other use cases in JENKINS-41339 .
            jglick Jesse Glick added a comment -
            withEnv(['PATH=$PATH:/extra/directory/bin'])
            

            is incorrect. You may use either

            withEnv(["PATH=$PATH:/extra/directory/bin"])
            

            (interpolating the current value in Groovy) or

            withEnv(['PATH+EXTRA=/extra/directory/bin'])
            

            as documented in the withEnv step.

            jglick Jesse Glick added a comment - withEnv([ 'PATH=$PATH:/extra/directory/bin' ]) is incorrect. You may use either withEnv([ "PATH=$PATH:/extra/directory/bin" ]) (interpolating the current value in Groovy) or withEnv([ 'PATH+EXTRA=/extra/directory/bin' ]) as documented in the withEnv step.
            ericson2314 John Ericson added a comment -

            jglick I'm no fan of barely-planned string evaluation either, but I don't think it's not fair to simply say "freestyle jobs are broken": values in env may come from either the Jenkins GUI or groovy (e.g. withEnv) and there is no way of knowing. Long predating any pipeline work, the effective behavior of GUI-defined environment variables has been established that they may contain variable references. Freestyle jobs implement this, not define it.

            You can make that the semantics of withEnv if you want, but then to handle the GUI case correctly I see the only option being escaping the withEnv arguments before they are put in env so the GUI ones still get expanded correctly.

            ericson2314 John Ericson added a comment - jglick I'm no fan of barely-planned string evaluation either, but I don't think it's not fair to simply say "freestyle jobs are broken": values in env may come from either the Jenkins GUI or groovy (e.g. withEnv ) and there is no way of knowing. Long predating any pipeline work, the effective behavior of GUI-defined environment variables has been established that they may contain variable references. Freestyle jobs implement this, not define it. You can make that the semantics of withEnv if you want, but then to handle the GUI case correctly I see the only option being escaping the withEnv arguments before they are put in env so the GUI ones still get expanded correctly.

            People

              jglick Jesse Glick
              b_dean Ben Dean
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: