The heredoc approach is great, but you can't use it naively:
- There are issues with not preserving spaces and tabs in the pasted content, which are hard to read on-screen, and may be triggered by the auto-cleanup functions of your text editor
- If the end-of-heredoc marker you use occurs in the pasted content, the operation will end early -- problem if the content has its own heredoc and uses a common marker like 'EOF'.
This means a naive heredoc approach can succeed or fail depending on the exact content that's pasted in. That violates the principle of least amazement and is dangerous since semi-random.
I prefer an approach where the content is captured with base64 uuencode first. This eliminates the possibility of different behavior depending on content, so you never have to think about this again.
Safer approach:
- Identify the content to capture, say whatever.sh
uuencode -m whatever.sh whatever.sh >tmp
- Paste the contents of tmp into the script wrapper
- Use a heredoc marker that can't occur in base64
The final script looks like:
cat > file.tmp <<'_EOF'
begin-base64 644 whatever.sh
bHMgLWxSCmxzIC1sUgpscyAtbFIKbHMgLWxSCmxzIC1sUgpscyAtbFIKbHMg
LWxSCmxzIC1sUgpscyAtbFIKbHMgLWxSCmxzIC1sUgpscyAtbFIKbHMgLWxS
CmxzIC1sUgpscyAtbFIKbHMgLWxSCmxzIC1sUgpscyAtbFIKbHMgLWxSCmxz
IC1sUgpscyAtbFIK
====
_EOF
uudecode file.tmp
There is a tiny possibility that any line of uuencoded data could match your heredoc marker. You probably won't use markers that are 60 characters long :) but the last line can be shorter and there is a possibility the uuencoded content could accidentally match your marker, unless the marker uses a character (like underscore) that can't occur in base64 encoding. _EOF
is always safe.
It's also prudent to quote the heredoc marker like '_EOF'
to prevent shell variable expansion in the block. I don't think a base64 encoded payload can ever inadvertently reference a shell variable since $
isn't used in base64, but quoting eliminates this possibility. It also helps to establish the habit of always quoting the heredoc marker unless there's a reason you want shell expansion. This is another content-dependent behavior that's tricky since apparently random. ALWAYS quote your heredoc marker unless you know you want shell expansion within the content block!
The above is a manual procedure. It's easy to automate the same using templates.