Skip to content

Instantly share code, notes, and snippets.

@Faheetah
Last active October 26, 2024 16:38
Show Gist options
  • Save Faheetah/e11bd0315c34ed32e681616e41279ef4 to your computer and use it in GitHub Desktop.
Save Faheetah/e11bd0315c34ed32e681616e41279ef4 to your computer and use it in GitHub Desktop.
Jenkinsfile idiosynchrasies with escaping and quotes
node {
echo 'Results included as an inline comment exactly how they are returned as of Jenkins 2.121, with $BUILD_NUMBER = 1'
echo 'No quotes, pipeline command in single quotes'
sh 'echo $BUILD_NUMBER' // 1
echo 'Double quotes are silently dropped'
sh 'echo "$BUILD_NUMBER"' // 1
echo 'Even escaped with a single backslash they are dropped'
sh 'echo \"$BUILD_NUMBER\"' // 1
echo 'Using two backslashes, the quotes are preserved'
sh 'echo \\"$BUILD_NUMBER\\"' // "1"
echo 'Using three backslashes still results in only preserving the quotes'
sh 'echo \\\"$BUILD_NUMBER\\\"' // "1"
echo 'To end up with \" use \\\\\\" (yes, six backslashes)'
sh 'echo \\\\\\"$BUILD_NUMBER\\\\\\"'
echo 'This is fine and all, but we cannot substitute Jenkins variables in single quote strings'
def foo = 'bar'
sh 'echo "${foo}"' // (returns nothing)
echo 'This does not interpolate the string but instead tries to look up "foo" on the command line, so use double quotes'
sh "echo \"${foo}\"" // bar
echo 'Great, more escaping is needed now. How about just concatenate the strings? Well that gets kind of ugly'
sh 'echo \\\\\\"' + foo + '\\\\\\"' // \"bar\"
echo 'We still needed all of that escaping and mixing concatenation is hideous!'
echo 'There must be a better way, enter dollar slashy strings (actual term)'
def command = $/echo \\\"${foo}\\\"/$
sh command // \"bar\"
echo 'String interpolation works out of the box as well as environment variables, escaped with double dollars'
def vash = $/echo \\\"$$BUILD_NUMBER\\\" ${foo}/$
sh vash // \"3\" bar
echo 'It still requires escaping the escape but that is just bash being bash at that point'
echo 'Slashy strings are the closest to raw shell input with Jenkins, although the non dollar variant seems to give an error but the dollar slash works fine'
}
@vmiliantsei
Copy link

You just need to escape the $:

pipeline {
	environment {
		TEST = "It's easy!"
	}

	stages {
		stage('Test') {
			steps {
				sh 'echo "\$BUILD_NUMBER:   \$TEST"'
			}
		}
	}
}

Works as expected:

[Pipeline] sh
+ echo '1:   It'\''s easy!'
1:   It's easy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment