I want to create a bash script that reads a "payload" of binary data from an external file and spit out another bash script with this data escaped and encapsulated inside a string variable. Example:

  • mydata.bin - The source data: a binary data file to be encapsulated
  • myencoder.sh - The main perpetrator: a bash script that converts the binary data to a script with string variable
  • mypayload.sh - The end result: a bash script generated by myencoder.sh that contains the encoded data as a string variable.

To use this I would run myscript.sh mydata.bin mypayload.sh and myscript.sh would convert/escape/wrap/whatever the mydata.bin file into mypayload.sh

After running this command, the mypayload.sh file would look something like this:

# Generated by myencoder.sh with data from mydata.bin
encoded_data="[...]ugly escaped string representation of the binary data found in mydata.bin[...]"

The problem I am facing that I amunsure how to solve is how the data would be properly encoded. I read that printf "%q" could be used to escape strings, but how to invoke it on data fetched from an external binary file eluded me completely.

So please, any stabs at this and any tips are welcome!

PS: I don't want to introduce any dependencies outside of bash if possible. Depending on bash 4.x features is OK.

PPS: The encoding should favour small size and encoding/decoding performance.

  • Escaping binary data in your script sounds difficult. Have you looked into here documents to do the same? tldp.org/LDP/abs/html/here-docs.html – Mogget Oct 16 '15 at 12:34
  • Bash data can't contain the null byte. Use an external tool. – choroba Oct 16 '15 at 12:35
  • @Mogget: I am unsure how heredocs will help at all. I will still need to escape, and if that is not possible there is no solution. – Lennart Rolland Nov 1 '15 at 0:33

It's very hard to handle zero bytes from bash. You can output a zero byte by

printf %c

but you can't store it in a variable.

It's far easier to use external tools:

xxd < mydata.bin > encoded
xxd -r < encoded > binary
| improve this answer | |

This is not a complete solution to your problem; as others have mentioned dealing with NULLs in your input file is difficult in bash, and I'm sure potential of unicode input files could cause even more headaches.

But I put a little time into thinking how you might use printf %q in bash to do something similar to your suggestion and came up with this quick hack:

echo -n 'myvar="'
while read -r; do
  if [ ! -z "$REPLY" ]; then
    printf %q "$REPLY"
  echo -n '\n'
echo '"'

I'm sure it could break in many ways but maybe it might satisfy some part of your curiosity.

| improve this answer | |

This reply does not answer the question directly because apparently containing 0 bytes in bash variables is not possible and apparently there is no way to escape them into strings that can be safely kept inside bash variables without relying on external tools like xxd or uuencode that are not available by default on the platforms where my script will run.

However this was the solution that I ended up pursuing because it solved my problem closest, namely creating a script that holds arbitrary binary data as a payload that can be handled by the very script that holds it.

I used this article as my source. Basically the approach uses a separator string between the script and the binary data and never lets the bash interpreter reach the binary part at the end.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.