echo bytes to a file
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).
Related videos on Youtube
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, 2022Comments
-
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 about 10 yearsI got it to work with quotes, double quotes though. I kinda new it was something obvious. Thanks!
-
Ouki about 10 yearsThe thing is
echo
is usually a builtin command. So this is up to the shell you are using. The linux default beingbash
;\xHH
is properly displaying a character through its hexadecimal value. -
Ouki about 10 yearsJust be carefull as echo is (usually) a builtin shell command.
bash
handle\xHH
properly, but not all shells do. -
X Tian about 10 yearsYou are absolutely correct, my bad. See my edit 1 update.
-
Stéphane Chazelas almost 8 yearsOr just
perl -e 'print pack "c*", 0x66, 0x6f, 0x6f'
orperl -e 'print pack "H*", "666f6f"'
-
Stéphane Chazelas almost 8 yearsNote that
printf %b '\x66'
is not portable.printf '\x66'
is slightly more portable (works withksh93
, still not withdash
noryash
).printf '\146\157\157'
orprintf %b '\0146\0157\0157'
would be portable/standard.