Skip to content

Commit

Permalink
Use single quotes to export variables.
Browse files Browse the repository at this point in the history
That way, we only need to escape single quotes, nothing else.

Single quotes cannot be escaped using baslash, as that is treated
literally inside single quotes.
I.e. to get a literal single quotes, we have to break out of the
single quotes and escape it outside. "Simple".

So "it's cool" becomes 'it'\''s cool,i',

Treated by the shell as the concatenation of "it", "'", and "s cool".

See e.g. https://stackoverflow.com/a/1315213.
  • Loading branch information
Martin Sander committed Oct 13, 2017
1 parent c912545 commit 3b2132b
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@
import io.fabric8.kubernetes.client.dsl.ExecListener;
import io.fabric8.kubernetes.client.dsl.ExecWatch;
import okhttp3.Response;
import org.apache.commons.lang.StringEscapeUtils;
import org.jenkinsci.plugins.workflow.steps.EnvironmentExpander;

/**
Expand Down Expand Up @@ -245,9 +244,14 @@ public void kill(Map<String, String> modelEnvVars) throws IOException, Interrupt
private void setupEnvironmentVariable(EnvVars vars, ExecWatch watch) throws IOException
{
for (Map.Entry<String, String> entry : vars.entrySet()) {
watch.getInput().write(
String.format("export %s=\"%s\"%s", entry.getKey(), StringEscapeUtils.escapeJava(entry.getValue()), NEWLINE).getBytes(StandardCharsets.UTF_8));
}
watch.getInput().write(
String.format(
"export %s='%s'\n",
entry.getKey(),
entry.getValue().replace("'", "'\\''")
).getBytes(StandardCharsets.UTF_8)
);
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ public void runWithEnvVariablesInContext() throws Exception {
r.assertLogContains("The value of AFTER_QUOTE is AFTER_QUOTE\"", b);
r.assertLogContains("The value of ESCAPED_QUOTE is \\\"ESCAPED_QUOTE", b);
r.assertLogContains("The value of AFTER_ESCAPED_QUOTE is AFTER_ESCAPED_QUOTE\\\"", b);
r.assertLogContains("The value of SINGLE_QUOTE is BEFORE'AFTER", b);
r.assertLogContains("The value of WITH_NEWLINE is before newline\nafter newline", b);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//noinspection GrPackage
podTemplate(label: 'mypod',
containers: [
containerTemplate(name: 'busybox', image: 'busybox', ttyEnabled: true, command: '/bin/cat'),
Expand All @@ -6,22 +7,27 @@ podTemplate(label: 'mypod',
env.FROM_ENV_DEFINITION = "ABC"
node ('mypod') {
stage('Run busybox') {
withEnv(['FROM_WITHENV_DEFINITION=DEF',
'WITH_QUOTE="WITH_QUOTE',
'AFTER_QUOTE=AFTER_QUOTE"',
'ESCAPED_QUOTE=\\"ESCAPED_QUOTE',
'AFTER_ESCAPED_QUOTE=AFTER_ESCAPED_QUOTE\\"'
withEnv([
'FROM_WITHENV_DEFINITION=DEF',
'WITH_QUOTE="WITH_QUOTE',
'AFTER_QUOTE=AFTER_QUOTE"',
'ESCAPED_QUOTE=\\"ESCAPED_QUOTE',
"SINGLE_QUOTE=BEFORE'AFTER",
'AFTER_ESCAPED_QUOTE=AFTER_ESCAPED_QUOTE\\"',
'WITH_NEWLINE=before newline\nafter newline'
]) {
container('busybox') {
sh 'echo inside container'
sh """
echo The value of FROM_ENV_DEFINITION is \$FROM_ENV_DEFINITION
echo The value of FROM_WITHENV_DEFINITION is \$FROM_WITHENV_DEFINITION
echo The value of WITH_QUOTE is \$WITH_QUOTE
echo The value of AFTER_QUOTE is \$AFTER_QUOTE
echo The value of ESCAPED_QUOTE is \$ESCAPED_QUOTE
echo The value of AFTER_ESCAPED_QUOTE is \$AFTER_ESCAPED_QUOTE
"""
sh '''
echo "The value of FROM_ENV_DEFINITION is $FROM_ENV_DEFINITION"
echo "The value of FROM_WITHENV_DEFINITION is $FROM_WITHENV_DEFINITION"
echo "The value of WITH_QUOTE is $WITH_QUOTE"
echo "The value of AFTER_QUOTE is $AFTER_QUOTE"
echo "The value of ESCAPED_QUOTE is $ESCAPED_QUOTE"
echo "The value of AFTER_ESCAPED_QUOTE is $AFTER_ESCAPED_QUOTE"
echo "The value of SINGLE_QUOTE is $SINGLE_QUOTE"
echo "The value of WITH_NEWLINE is $WITH_NEWLINE"
'''
}
}
}
Expand Down

0 comments on commit 3b2132b

Please sign in to comment.