Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I'm trying to base64 encode an image in a shell script and put it into variable:

test="$(printf DSC_0251.JPG | base64)"
echo $test
RFNDXzAyNTEuSlBH

I've also tried something like this:

test=\`echo -ne DSC_0251.JPG | base64\`

but still with no success.

I want to do something like this:

curl -v -X POST -d '{"image":$IMAGE_BASE64,"location":$LOCATION,"time_created":$TIMECREATED}' -H 'Content-type: text/plain; charset=UTF8' http://192.168.1.1/upload

I found this http://www.zzzxo.com/q/answers-bash-base64-encode-script-not-encoding-right-12290484.html

but still have had no success.

You need to use cat to get the contents of the file named 'DSC_0251.JPG', rather than the filename itself.

test="$(cat DSC_0251.JPG | base64)"

However, base64 can read from the file itself:

test=$( base64 DSC_0251.JPG )
                with cat it works, great thanks a lot man. I know that it can read from file, but it still has problems to store it in variable so test="$(cat DSC_0251.JPG | base64)" works for me.
– dash00
                Jun 4, 2013 at 13:21
                What problems? The two commands above should produce identical results, except the first is a useless use of cat.
– chepner
                Jun 4, 2013 at 13:27
                you are right. This is what should I do $RESPONSE="$(curl -v -X POST -d '{"image":`base64|$DIR$IMAGE`,"location":$LOCATION,"time_created":$TIMECREATED}' -H 'Content-type: text/plain; charset=UTF8' --max-time 180 -s $URL)";
– dash00
                Jun 4, 2013 at 13:51
                What's wrong with base64 DSC_0251.JPG? There is no need to run through the cat filter when the program takes a file as arguments (base64 [OPTIONS] [FILE])
– Eric
                Feb 13, 2018 at 8:39

On OSX

On OSX, the base64 binary is different, and the parameters are different. If you want to use it on OSX, you should remove -w 0.

Single line result:

base64 DSC_0251.JPG

For HTML:

echo "data:image/jpeg;base64,$(base64 DSC_0251.JPG)"

As file:

base64 DSC_0251.JPG > DSC_0251.JPG.base64

In variable:

IMAGE_BASE64="$(base64 DSC_0251.JPG)"

In variable for HTML:

IMAGE_BASE64="data:image/jpeg;base64,$(base64 DSC_0251.JPG)"

Generic OSX/Linux

As Shell Function

@base64() {
  if [[ "${OSTYPE}" = darwin* ]]; then
    # OSX
    if [ -t 0 ]; then
      base64 "$@"
      cat /dev/stdin | base64 "$@"
    # Linux
    if [ -t 0 ]; then
      base64 -w 0 "$@"
      cat /dev/stdin | base64 -w 0 "$@"
# Usage
@base64 DSC_0251.JPG
cat DSC_0251.JPG | @base64

As Shell Script

Create base64.sh file with following content:

#!/usr/bin/env bash
if [[ "${OSTYPE}" = darwin* ]]; then
  # OSX
  if [ -t 0 ]; then
    base64 "$@"
    cat /dev/stdin | base64 "$@"
  # Linux
  if [ -t 0 ]; then
    base64 -w 0 "$@"
    cat /dev/stdin | base64 -w 0 "$@"

Make it executable:

chmod a+x base64.sh

Usage:

./base64.sh DSC_0251.JPG
cat DSC_0251.JPG | ./base64.sh

Decode

Get you readable data back:

base64 -d DSC_0251.base64 > DSC_0251.JPG 
                -w 0 this parameter is very important in many cases. Ex. If we are running directly into the command line. Thanks!
– Jayesh Dhandha
                Jun 5, 2018 at 5:21
                BTW on OSX I'm getting base64: invalid option -- w. When it's removed, I get Unable to open '0': No such file or directory. See this instead.
– coblr
                Jun 14, 2018 at 18:58

Please be very cautious when using echo (as many answers here), because it will add a newline character at the end, distorting your encoded string (leading to e.g. incorrect passwords) due to these ominous extra encoded characters: Cg== added at the end of the encoded string:

For example, if we have this string to encode:

$ MINIO_SECRET_KEY=VsarGnNADHGv

With `printf' it will look like this (correct):

$ AWS_SECRET_ACCESS_KEY="$(printf $MINIO_SECRET_KEY | base64)" && echo $AWS_SECRET_ACCESS_KEY
VnNhckduTkFESEd2

... but with echo like this (incorrect):

$ AWS_SECRET_ACCESS_KEY="$(echo $MINIO_SECRET_KEY | base64)" && echo $AWS_SECRET_ACCESS_KEY
VnNhckduTkFESEd2Cg==
                Please make more obvious what additional insight you contribute beyond existing and better explained answers. I.e. what is the difference of your solution and why is it a relevant advantage over what was already given?
– Yunnosch
                Mar 29 at 6:26
                I tried all of the other solutions in this post myself and none would work as it now needs a -i switch in order to specify the file name to be used.
– Amir Hajiha
                Mar 30 at 10:01
                Interesting, please edit to improve your answer post with that explanation. Make sure to explain what "now" means. What changed, when, how, why?
– Yunnosch
                Mar 30 at 11:35
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.