echo bytes to a file

165,074

Solution 1

You have to take your codes into quotes:

echo -n -e '\x66\x6f\x6f' > byteFileForNow

cause otherwise shell replaces \x to x before it goes to echo -e.

ps. double escape will also work:

echo -n -e \\x66\\x6f\\x6f > byteFileForNow

Solution 2

Shell

In shell you can use printf:

printf "%b" '\x66\x6f\x6f' > file.bin

Note: %b - Print the associated argument while interpreting backslash escapes.

Perl

With perl, it is even simpler:

perl -e 'print pack("ccc",(0x66,0x6f,0x6f))' > file.bin

Python

If you've Python installed, try the following one-liner:

python -c $'from struct import pack\nwith open("file.bin", "wb") as f: f.write(pack("<bbb", *bytearray([0x66, 0x6f, 0x6f])))'


Testing:

$ hexdump file.bin 
0000000 66 6f 6f 

Solution 3

There's a lot of information in the online manual for each command; it is always worth having a look at that before giving up and posting a question.

man echo explains which escape sequences are allowed. Here's an extract.

   If -e is in effect, the following sequences are recognized:

   \0NNN  the character whose ASCII code is NNN (octal)

   \\     backslash

   \a     alert (BEL)

   \b     backspace

   \c     produce no further output

   \f     form feed

   \n     new line

   \r     carriage return

   \t     horizontal tab

   \v     vertical tab

So \x86 is just incorrect. it must be octal and put your string in double quotes, otherwise it will be interpreted by the shell.

Example:

$ echo -e -n "\033\07\017" >tf
$ od -c tf
0000000 033  \a 017
0000003

Edit 1

As Ouki reminded me, echo is also a shell builtin, so the information is in the manual page for bash, man bash; here's the relevant section. But use quotes " around your string to stop the shell interpreting the back slashes.

   echo [-neE] [arg ...]
          Output  the  args, separated by spaces, followed by a newline.  The return status is always
          0.  If -n is specified, the trailing newline is suppressed.  If the  -e  option  is  given,
          interpretation  of  the  following  backslash-escaped characters is enabled.  The -E option
          disables the interpretation of these escape characters, even  on  systems  where  they  are
          interpreted  by  default.   The  xpg_echo shell option may be used to dynamically determine
          whether or not echo expands these escape characters by default.  echo does not interpret --
          to mean the end of options.  echo interprets the following escape sequences:
          \a     alert (bell)
          \b     backspace
          \c     suppress further output
          \e     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \0nnn  the eight-bit character whose value is the octal value nnn (zero to three octal dig‐
                 its)
          \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex dig‐
                 its)

Solution 4

This might not answering directly the question, but you can also use vi in hex mode:

Open your file and type: ESC :%!xxd to switch into hex mode.

You will be able to edit the hex part (the text part will not be updated as you change the hex part).

When your are done hit escape again and type: ESC :%!xxd -r to write back the changes you did in hex mode (don't forget to save afterward).

Share:
165,074

Related videos on Youtube

Mark
Author by

Mark

Currently studying engineering with focus on Mechatronics and IT. Languages: German, English, Java, C#, C, Assembler and some derviates of the latter 2. Interests are home automation and especially home networking: Someday I'll email my kitchen to make me a coffee!

Updated on September 18, 2022

Comments

  • Mark
    Mark over 1 year

    I'm trying to connect my rasberry Pi to some display using the i2c bus. To get started I wanted to manually write stuff, bytes in particular to a file. How do you write specific bytes to a file? I already read that one and I figured my problem should be solved by something like this

    echo -n -e \x66\x6f\x6f > byteFileForNow
    

    However, when I open up that file with nano, instead of foo I see:

    x66x6fx6f

    So the backslashes were escaped, but not the bytes themselves. I also tried the same only without the -e this time, so I would've exepected to see \x66\x6f\x6f, but got the same as before.

    So echo is escaping backslashes, backslashes alone and backslashes regardless of if it is supposed to.
    Any idea how to fix this?
    According to the man-page that should've done what I'm looking for.

  • Mark
    Mark about 10 years
    I got it to work with quotes, double quotes though. I kinda new it was something obvious. Thanks!
  • Ouki
    Ouki about 10 years
    The thing is echo is usually a builtin command. So this is up to the shell you are using. The linux default being bash; \xHH is properly displaying a character through its hexadecimal value.
  • Ouki
    Ouki about 10 years
    Just be carefull as echo is (usually) a builtin shell command. bash handle \xHH properly, but not all shells do.
  • X Tian
    X Tian about 10 years
    You are absolutely correct, my bad. See my edit 1 update.
  • Stéphane Chazelas
    Stéphane Chazelas almost 8 years
    Or just perl -e 'print pack "c*", 0x66, 0x6f, 0x6f' or perl -e 'print pack "H*", "666f6f"'
  • Stéphane Chazelas
    Stéphane Chazelas almost 8 years
    Note that printf %b '\x66' is not portable. printf '\x66' is slightly more portable (works with ksh93, still not with dash nor yash). printf '\146\157\157' or printf %b '\0146\0157\0157' would be portable/standard.