I need to run a Bash script that can echo a 300 lines of Groovy script to a tmp file. What's the best way to do it ?
My current workaround is putting the script file online and download it.
Use the heredoc syntax to embed the other script within a shell script:
cat > file.tmp <<'endmsg'
script goes here...
endmsg
The heredoc approach is great, but you can't use it naively:
This means a naive heredoc approach can succeed or fail depending on the content that's pasted in. That violates the principle of least amazement and is dangerous since semi-random.
I prefer wrapping the content with base64 uuencode. This eliminates the possibility of different behavior depending on the content, so you never have to think about this again.
Safer approach:
uuencode -m whatever.sh whatever.sh >tmpThe 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 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 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. 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.
uudecode -o decoded_outfile < ./file.tmp This took me a minute to figure out. uudecode file.tmp by itself doesn't appear to do anything.When you want to output to a file that requires you to use sudo, the answer is totally non-obvious!
sudo tee /etc/php/conf.d/xdebug.ini > /dev/null <<'TXT'
zend_extension=xdebug.so
xdebug.remote_enable=on
xdebug.remote_autostart=on
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp
TXT
cat script > tmp?