echo bajtów do pliku

46

Próbuję podłączyć rasberry Pi do jakiegoś wyświetlacza za pomocą magistrali i2c. Na początek chciałem ręcznie zapisać rzeczy, w szczególności bajty do pliku. Jak zapisujesz określone bajty w pliku? Już to przeczytałem i pomyślałem, że mój problem powinien zostać rozwiązany przez coś takiego

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

Jednak kiedy otwieram ten plik za pomocą nano, zamiast foo widzę:

x66x6fx6f

Tak więc uniknięto ukośników odwrotnych, ale nie samych bajtów. Próbowałem tego samego tylko bez -e tym razem, więc oczekiwałbym zobaczenia \ x66 \ x6f \ x6f , ale dostałem to samo, co wcześniej.

Tak więc echo ucieka przed odwrotnym ukośnikiem, samym odwrotnym i odwrotnym niezależnie od tego, czy ma to zrobić.
Jakiś pomysł jak to naprawić?
Według strony podręcznika, która powinna była zrobić to, czego szukam.

znak
źródło

Odpowiedzi:

65

Musisz wziąć swoje kody w cytaty:

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

ponieważ w przeciwnym razie powłoka zamienia \xsię, xzanim do niej przejdzie echo -e.

ps. podwójna ucieczka będzie również działać:

echo -n -e \\x66\\x6f\\x6f > byteFileForNow
wysypka
źródło
Mam go do pracy z cytatami, choć podwójnymi. Niby nowe, to było coś oczywistego. Dzięki!
Mark
Bądź ostrożny, ponieważ echo jest (zwykle) wbudowanym poleceniem powłoki. bashobsługiwać \xHHpoprawnie, ale nie wszystkie powłoki tak.
Ouki,
5

Muszla

W powłoce możesz użyć printf:

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

Uwaga: %b- Wydrukuj powiązany argument podczas interpretacji znaków ukośnika odwrotnego.

Perl

W perlu jest to jeszcze prostsze:

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

Pyton

Jeśli masz zainstalowany Python, wypróbuj następującą linijkę:

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


Testowanie:

$ hexdump file.bin 
0000000 66 6f 6f 
kenorb
źródło
1
Albo po prostu perl -e 'print pack "c*", 0x66, 0x6f, 0x6f'alboperl -e 'print pack "H*", "666f6f"'
Stéphane Chazelas
2
Pamiętaj, że printf %b '\x66'nie jest przenośny. printf '\x66'jest nieco bardziej przenośny (działa z ksh93, wciąż nie z dashnor yash). printf '\146\157\157'lub printf %b '\0146\0157\0157'byłby przenośny / standardowy.
Stéphane Chazelas
2

Może to nie odpowiadać bezpośrednio na pytanie, ale możesz również użyć viw trybie szesnastkowym:

Otwórz plik i wpisz: ESC, :%!xxd aby przełączyć na tryb szesnastkowy.

Będziesz mógł edytować część heksadecymalną (część tekstowa nie będzie aktualizowana podczas zmiany części heksadecymalnej).

Po zakończeniu naciśnij klawisz Escape, a następnie wpisz: ESC, :%!xxd -r aby zapisać zmiany dokonane w trybie szesnastkowym (nie zapomnij zapisać później).

Ouki
źródło
2

W każdym podręczniku online znajduje się wiele informacji; zawsze warto się temu przyjrzeć, zanim zrezygnujesz i zadasz pytanie.

man echowyjaśnia, które sekwencje specjalne są dozwolone. Oto wyciąg.

   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

Więc \ x86 jest po prostu niepoprawny. musi być ósemkowy i zawierać ciąg znaków w cudzysłowie, w przeciwnym razie zostanie zinterpretowany przez powłokę.

Przykład:

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

Edytuj 1

Jak przypomniał mi Ouki, echo jest również wbudowane w powłokę, więc informacje znajdują się na stronie podręcznika bash man bash; oto odpowiednia sekcja. Ale używaj cudzysłowu " wokół łańcucha, aby zatrzymać interpretację powłoki przez ukośniki odwrotne.

   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)
X Tian
źródło
1
Rzecz w tym, że echozazwyczaj jest to wbudowane polecenie. To zależy od używanej powłoki. Domyślnym linuxem jest bash; \xHHprawidłowo wyświetla znak poprzez jego wartość szesnastkową.
Ouki,
1
Masz absolutną rację, mój zły. Zobacz moją aktualizację edit 1.
X Tian