Can a bash heredoc put its result directly into a variable?
bash
Solution
How to put a here-string into a variable in Bash:
In Bash use `read` with the `-d` delimiter set to null:
IFS= read -r -d '' cmd <<EOC
...blah blah...
EOC
Make sure you really use `IFS=` like shown, in front of `read`, otherwise any leading and trailing spaces will be trimmed. Make sure you use `-r` otherwise some backslashes would be understood as escape backslashes.
Some would argue that it's simpler to just use a plain assignment as:
cmd='
...blah blah...
'
But sometimes you have lots of quotes to the point that it becomes simpler and nicer to use this.
Subtle note. With this, `read` returns a failure return code (1) since the null-byte delimiter is not read before EOF. While this is alright most of the times, it can be a problem if you're using `set -e` (but you really shouldn't use `set -e` anyway). If you want to be sure, add:
IFS= read -r -d '' cmd <<EOC || true
...blah blah...
EOC
Now, seriously, about your problem.
Below is a serious note that you really should take into account: don't put code into strings! it's broken!. Instead, use a function or (still bad, but not broken) an array. Here's how you would use an array:
mycommand=(
docker run
-p "$MY_IP:$LOCAL_PORT:$LOCAL_PORT"
-p "$MY_IP:$PEER_PORT:$PEER_PORT"
-v "$CERT_DIR":/cert
"$ETCD_IMAGE"
--name "$MACHINE.$DOMAIN"
--peer-cert-file=/cert/server-cert.pem
--peer-key-file=/cert/server-key.pem
--peer-ca-file=/cert/ca.pem
--peer-addr="$MY_IP:$PEER_PORT"
--peers="$OIPPC"
)
(observe the quotes that I took time to type, with love). Then you can safely run it (by safely I mean it's all right if you're having glob characters or quotes or spaces in your arguments) as:
"${mycommand[@]}"
(observe the healthy quotes, again). If you want to print the command, use this:
printf '%s\n' "${mycommand[*]}"
Unfortunately, the line breaks won't be preserved here. But really, that shouldn't be a problem at all. If really needed, you should pass this command through a formatter of some sort (well, very likely it doesn't exist so you'll have to code it yourself). But put the things in the right order: you want to define a command, to execute it (and, optionally format it, for user display), not the other way round, have a string that's nice to the user's eyes that you then have to parse (dangerously) to transform into code.
Problem
I have some code like this: ``` CMD=$(cat <<EOC docker run -p $MY_IP:$LOCAL_PORT:$LOCAL_PORT -p $MY_IP:$PEER_PORT:$PEER_PORT -v $CERT_DIR:/cert $ETCD_IMAGE --name $MACHINE.$DOMAIN --peer-cert-file=/cert/server-cert.pem --peer-key-file=/cert/server-key.pem --peer-ca-file=/cert/ca.pem --peer-addr=$MY_IP:$PEER_PORT --peers=$OIPPC EOC ) ``` is there a way to get a here doc to assign result directly to variable in bash without intervening process (cat)? This code works, it just feels like too much work.