macOS Base64 encode script
I am working on macOS and I wanted to base64 encode a snippet of json text. For example I have the following JSON snippet.
{
"array": [
1,
2,
3
],
"boolean": true,
"color": "gold",
"null": null,
"number": 123,
"object": {
"a": "b",
"c": "d"
},
"string": "Hello World"
}I want to run a command to encode this as base64 text. I need this because I am working with AWS Kinesis and I want to insert a new event into the stream (put-record). That means I need to turn this snippet into the following format
aws kinesis put-record \
--stream-name samplestream \
--data sampledatarecord_in_base64 \
--partition-key samplepartitionkeyLooking into the man pages of macOS and I find base64 command tool. Problem solved or so I thought until checking the man page.
BINTRANS(1) General Commands Manual BINTRANS(1)
NAME
bintrans, uuencode, uudecode, b64encode, b64decode, base64 β encode / decode a binary file
SYNOPSIS
bintrans [algorithm] [...]
uuencode [-m] [-r] [-o output_file] [file] name
uudecode [-cimprs] [file ...]
uudecode [-i] -o output_file
b64encode [-r] [-w column] [-o output_file] [file] name
b64decode [-cimprs] [file ...]
b64decode [-i] -o output_file [file]
base64 [-h | -D | -d] [-b count] [-i input_file] [-o output_file]This command expects input/output files and I want to do copy/paste text like linux standard tool uses which is available if you want to use the homebrew version here. However I am not going to do that because I am going to write a script overlay instead to practice some bash scripting.
I want to call a script like this to-base64.sh '<input json here>' and get out the base64 text.
That means from the above sample json first I flatten it into a single line that looks like this { "array": [ 1, 2, 3 ], "boolean": true, "color": "gold", "null": null, "number": 123, "object": { "a": "b", "c": "d" }, "string": "Hello World" } and then call the script to-base64.sh to get this output
eyAiYXJyYXkiOiBbIDEsIDIsIDMgXSwgImJvb2xlYW4iOiB0cnVlLCAiY29sb3IiOiAiZ29sZCIsICJudWxsIjogbnVsbCwgIm51bWJlciI6IDEyMywgIm9iamVjdCI6IHsgImEiOiAiYiIsICJjIjogImQiIH0sICJzdHJpbmciOiAiSGVsbG8gV29ybGQiIH0KTherefore my script needs to take the first argument and convert that text into base64
- Create an input
temp_input_file - Put contents of command line argument into
temp_input_file - Create a
temp_output_file - Run the
base64command with-i temp_input_file -o temp_output_file - Use cat command to put contents of
temp_output_fileto standard output - Caveat make sure to handle unexpected hang or interrupts in script to clear temporary files with bash
traphandler to cleanup and delete temp files.
Here is the final script. I also made sure to use the calling users bash instead of the #!/bin/bash which could be the system or some indeterminate bash.
#!/usr/bin/env bash
# Use the users bash to be consistent
tmp_input_file=$(mktemp)
tmp_output_file=$(mktemp)
[ "$?" -eq 0 ] || {
printf "error: mktemp had non-zero exit code.\n" >&2
exit 1
}
[ -f "$tmp_input_file" ] || {
printf "error: tempfile does not exist.\n" >&2
exit 1
}
trap 'rm -f "$tmp_input_file"' SIGTERM SIGINT EXIT
trap 'rm -f "$tmp_output_file"' SIGTERM SIGINT EXIT
cat > "$tmp_input_file" << eof
$1
eof
base64 -i "$tmp_input_file" -o "$tmp_output_file"
cat "$tmp_output_file"