Differences between revisions 6 and 9 (spanning 3 versions)
Revision 6 as of 2008-12-08 20:36:15
Size: 1967
Editor: 63
Comment:
Revision 9 as of 2009-03-07 20:04:46
Size: 2618
Editor: localhost
Comment: not really a workaround, just a recipe
Deletions are marked like this. Additions are marked like this.
Line 9: Line 9:
    var=$(uuencode /bin/ls -) ; uudecode <<<"$var" > ls  (don't forget the quotes!)     var=$(uuencode /bin/ls ls)
   cd /somewhere/else
   
uudecode <<<"$var" # don't forget the quotes!
Line 12: Line 14:
One instance where such would sometimes be handy is storing small temporary bitmaps while working with netpbm... here I resorted to adding an extra pnmnoraw to the pipe, creating (larger) ASCII files that bash has no problems storing).  ''Note: there is a huge difference between GNU and Unix uuencode/uudecode. With Unix uudecode, you ''cannot'' specify the output file; it always uses the filename encoded in the ASCII data. I've fixed the previous example so that it works on Unix systems. If you make further changes, please don't use GNUisms. Thanks.'' --GreyCat

One instance where such would sometimes be handy is storing small temporary bitmaps while working with netpbm... here I resorted to adding an extra pnmnoraw to the pipe, creating (larger) ASCII files that bash has no problems storing.
Line 38: Line 42:

To cat binary file with just bash builtins when no external command is available:{{{
#!/bin/bash
# simulate cat with just bash builtins, binary safe
IFS=
while read -d '' -r -n1 x ; do
    case "$x" in
        '') printf "\x00";;
        *) printf "%s" "$x";;
    esac
done
}}}

Can bash handle binary data?

The answer is, basically, no....

While bash won't have as many problems with it as older shells, it still can't process arbitrary binary data, and more specifically, shell variables are not 100% binary clean, so you can't store binary files in them.

You can store uuencoded ASCII data within a variable such as

    var=$(uuencode /bin/ls ls)
    cd /somewhere/else
    uudecode <<<"$var"  # don't forget the quotes!
  • Note: there is a huge difference between GNU and Unix uuencode/uudecode. With Unix uudecode, you cannot specify the output file; it always uses the filename encoded in the ASCII data. I've fixed the previous example so that it works on Unix systems. If you make further changes, please don't use GNUisms. Thanks. --GreyCat

One instance where such would sometimes be handy is storing small temporary bitmaps while working with netpbm... here I resorted to adding an extra pnmnoraw to the pipe, creating (larger) ASCII files that bash has no problems storing.

If you are feeling adventurous, consider this experiment:

    # bindec.bash, attempt to decode binary data to ascii decimals
    IFS=
    while read -n1 x ;do
        case "$x" in
            '') echo empty ;;
            # insert the 256 lines generated by the following oneliner here:
            # for x in $(seq 0 255) ;do echo "        $'\\$(printf %o $x)') echo $x;;" ;done
        esac
    done

and then pipe binary data into it, maybe like so:

    for x in $(seq 0 255) ;do echo -ne "\\$(printf %o $x)" ;done | bash bindec.bash | nl | less

This suggests that the 0 character is skipped entirely, because we can't create it with the input generation, enough to conveniently corrupt most binary files we try to process.

  • Yes, Bash is written in C, and uses C semantics for handling strings -- including the NUL byte as string terminator -- in its variables. You cannot store NUL in a Bash variable sanely. It simply was never intended to be used for this. - GreyCat

Note that this refers to storing them in variables... moving data between programs using pipes is always binary clean. Temporary files are also safe, as long as appropriate precautions are taken when creating them.

To cat binary file with just bash builtins when no external command is available:

# simulate cat with just bash builtins, binary safe
IFS=
while read -d '' -r -n1 x ; do
    case "$x" in
        '') printf "\x00";;
        *) printf "%s" "$x";;
    esac
done

BashFAQ/058 (last edited 2009-03-09 08:26:26 by pgas)