Johannes Ernst
Johannes Ernst

Reputation: 3176

bash multiple heredocs et al

I have a bash build script that I (well, Jenkins, but that's immaterial, this is a bash question) executes like this:

sudo -u buildmaster bash <<'END'
# do all sorts of crazy stuff here including using variables, like:
ARGS=something
ARGS="$ARGS or other"
# and so forth
END

Now I'd like to pass in a variable (Jenkins parameterized build), say PLATFORM. The trouble is that if I refer to $PLATFORM in my heredoc, it is undefined (I used 'END' to avoid variable substitution). If I turn the 'END' into END, my scripts becomes really unreadable with all the escapes I need to use.

So the question is, is there some (easy, readable) way of passing in two heredocs, one with quotes, and one without, into the same bash invocation? I was looking for something like this

sudo -u buildmaster bash <<PREFIX <<'END'
PLATFORM=$PLATFORM
PREFIX
# previous heredoc goes here
END

in the hope that it would simply concatenate, but I can't get the two heredocs to work (I guess bash is not Perl)

My fallback plan is to create temp files, but I was hoping there's a trick I don't know and that somebody could teach me :-)

Upvotes: 3

Views: 1697

Answers (2)

gniourf_gniourf
gniourf_gniourf

Reputation: 46823

In this case you could consider using bash with its -s argument:

sudo -u buildmaster bash -s -- "$PARAMETER" <<'END'
# do all sorts of crazy stuff here including using variables, like:
ARGS=something
ARGS="$ARGS or other"
# and so forth
PARAMETER=$1
END

(note that you have a syntax error, your closing END is quoted and shouldn't be).


There's another possibility (so that you have lots of options—and this one might be the simplest, if it applies) is to have your variables exported, and use the -E switch to sudo that exports the environment, e.g.,

export PARAMETER
sudo -E -u buildmaster bash <<'EOF'
# do all sorts of crazy stuff here including using variables, like:
ARGS=something
ARGS="$ARGS or other"
# and so forth
# you can use PARAMETER here, it's fine!
EOF

Along these lines, if you don't want to export everything, you may use env as follows:

sudo -u buildmaster env PARAMETER="$PARAMETER" bash <<'EOF'
# do all sorts of crazy stuff here including using variables, like:
ARGS=something
ARGS="$ARGS or other"
# and so forth
# you can use PARAMETER here, it's fine!
EOF

Upvotes: 3

Charles Duffy
Charles Duffy

Reputation: 295316

Substituted your quoted prefix into your unquoted full document:

# store the quoted part in a variable
prefix=$(cat <<'END'
ARGS=something
ARGS="$ARGS or other"
END
)

# use that variable in building the full document
sudo -u buildmaster bash <<END
$prefix
...
END

Upvotes: 2

Related Questions