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:


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.

4 Answers 4


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
  • I got it to work with quotes, double quotes though. I kinda new it was something obvious. Thanks!
    – Mark
    Mar 5, 2014 at 13:16
  • Just be carefull as echo is (usually) a builtin shell command. bash handle \xHH properly, but not all shells do.
    – Ouki
    Mar 5, 2014 at 13:26


In shell you can use printf:

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

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


With perl, it is even simpler:

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


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])))'


$ hexdump file.bin 
0000000 66 6f 6f 
  • 1
    Or just perl -e 'print pack "c*", 0x66, 0x6f, 0x6f' or perl -e 'print pack "H*", "666f6f"' Jun 14, 2016 at 21:06
  • 2
    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. Jun 14, 2016 at 21:11

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).


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.


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

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‐
          \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex dig‐
  • 2
    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
    Mar 5, 2014 at 13:24
  • 1
    You are absolutely correct, my bad. See my edit 1 update.
    – X Tian
    Mar 5, 2014 at 13:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .