przekazywanie dd pomiń | szukaj przesunięcia w systemie szesnastkowym

11
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=3 2> /dev/null
d
# dd if=2013-Aug-uptime.csv bs=1 count=1 skip=0x3 2> /dev/null
f

Dlaczego drugie polecenie generuje inną wartość?

Czy jest możliwe podanie przesunięcia pomijania | szukania ddjako wartości szesnastkowej?

eadmaster
źródło

Odpowiedzi:

18

Dlaczego drugie polecenie generuje inną wartość?

Ze względów historycznych dduważa xsię za operator mnożenia. Tak więc 0x3ocenia się na 0.

Czy jest możliwe przekazanie przesunięcia pomijania | szukania do dd jako wartości szesnastkowej?

O ile wiem, nie bezpośrednio. Oprócz mnożenia za pomocą operatora x, możesz dodać dowolną liczbę, baby oznaczać „pomnóż przez 512” (0x200) i przez K„pomnożyć przez 1024” (0x400). Z GNU dd można użyć przyrostki M, G, T, P, E, Zi Yoznacza mnożenie przez 2 odpowiednio do mocy 20, 30, 40, 50, 60, 70, 80 lub 90, można używać małe albo oprócz dla bsufiksu. (Istnieje wiele innych możliwych sufiksów. Na przykład EBoznacza „pomnóż przez 10 18 ” i PiB„pomnóż przez 2 50 ”. Aby info coreutils "block size"uzyskać więcej informacji, jeśli masz instalację GNU.)

Możesz znaleźć powyższe tajemne, anachroniczne i maniakalne do absurdu. Nie martw się: nie jesteś sam. Na szczęście możesz po prostu zignorować to wszystko i zamiast tego użyć podstawienia arytmetycznego powłoki (bash i inne powłoki zgodne z Posix będą działać, a także niektóre powłoki inne niż Posix). Powłoka rozumie liczby szesnastkowe i pozwala na pełny zakres operatorów arytmetycznych zapisanych w normalny sposób. Musisz tylko otoczyć to wyrażenie $((...)):

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))
rici
źródło
Zauważ, że $((...))jest to rozszerzenie arytmetyczne POSIX, w ogóle nie jest specyficzne dla bash, nie musisz go używać bash, każda powłoka POSIX zrobi. Należy jednak pamiętać, że w wielu powłokach bash, w tym również ulega podziałowi słów, dlatego należy zacytować.
Stéphane Chazelas,
@StephaneChazelas: To prawda, to nie jest specyficzne dla bash. Jednak nie potrzebuje cytatów. (Posix: „Wyrażenie należy traktować tak, jakby było w cudzysłowie, z wyjątkiem tego, że podwójny cudzysłów w wyrażeniu nie jest traktowany specjalnie.”) Jeśli w wyrażeniu była zmienna, a jej wartość zawierała separator, to nie byłby prawidłowy numer; umieszczanie cudzysłowów $((...))niczego nie zmieni. Jedynym przypadkiem, w którym potrafię wymyślić, gdzie cytaty by coś zrobiły, jest coś takiego, IFS=4ale spowodowałoby to różnego rodzaju chaos.
rici
Część, którą zacytowałeś, dotyczy tego, co jest w środku $((...)). POSIX jest jasne, że rozszerzenie $((...))podlega podziałowi słów . Pozostawienie dowolnego cudzysłowu polecenia / arytmetyki / zmiennej bez cudzysłowu w kontekście listy to operator split + glob. Ustawienie IFS = 4 nie spowodowałoby różnego rodzaju problemów, jeśli nie użyjesz operatora split + glob tam, gdzie nie jest to potrzebne / potrzebne, i ustawisz IFS za każdym razem, gdy potrzebujesz tego operatora split + glob.
Stéphane Chazelas,
@StephaneChazelas: tak, wynik liczbowy podlega podziałowi słów. Ale to liczba całkowita. Jeśli wybierzesz IFScoś, co zawiera cyfry, coś, co nie wydaje mi się, żebym kiedykolwiek zrobił, to musisz zacytować. Można przypuszczać, że gdyby to robił, byłby świadomy tej potrzeby, ponieważ nie jest to coś, co można by zrobić swobodnie. A przynajmniej nie jest to coś, co prawdopodobnie zrobię, kropka. Nie chcę mówić za ciebie.
rici
1
@ogurets: jakiej powłoki używasz? (Proszę dołączyć wersję).
rici
0

Wiem, że to stary wątek, ale problem jest wciąż tak samo aktualny, jak zawsze, szczególnie gdy idioci tacy jak ja idą i mimowolnie przywołują i wycinają „plik CP pliku A plik B” z historii bash, gdy plik B nie jest jeszcze zarejestrowany, aby Git nie miał kopii zapasowej i zawierający kilka godzin kodowania po prawie nocy: - /

Dzięki koncepcjom w tym wątku udało mi się w pełni odzyskać utracony plik, jednak zgubiłem mój na zdalnym wirtualnym serwerze prywatnym z dyskiem 32 Gb i bardzo małą pamięcią RAM (z systemem Ubuntu 18.04), a wszystkie moje próby za pomocą 'grep' jako powyżej szybko umrze z „niewystarczającą pamięcią”

W moim przypadku to właśnie mi hexdump -C /dev/sdX1 | grep 'shortString'przyszło na ratunek. W przeciwieństwie do grep, wyświetla on tylko bardzo wąską reprezentację heksadecymalną ASCII, dlatego bardzo ważne jest, aby szukać tylko krótkiego unikalnego ciągu znaków i pamiętać, że nawet to można owinąć. Gdy wyprowadził jakiś adres szesnastkowy, w którym było dopasowanie, mogłem użyć „dd” w podobny sposób, jak powyżej, z tym wyjątkiem, że wydawało mi się, że domyślnie jest to rozmiar bloku 4096, więc nie tylko musiałem zamień adres bajtów szesnastkowych na dziesiętny, ale podziel go przez 4096, aby przeskalować go do 4k bloków dla parametru pomijania dd - nieprzydatnie, jeśli ta liczba jest zbyt duża dla dd, komunikat o błędzie wygląda, jakby narzekał, że skip=jest niepoprawny, a nie przekazaną mu liczbę .

Uznanie dla ludzi, którzy dodali wskazówki dotyczące używania basha z $((0xabcd))łatwą konwersją hex-> dec konwersji :-)

Tylko moje ostatnie słowo - w moim przypadku było kilka kopii tego samego pliku, które wszystkie były blisko siebie. Ale odejmując najniższy adres od najwyższego adresu zgłoszonego przez zrzut heksowy, udało mi się zidentyfikować ~ 5 MB regionu zawierającego wszystkie możliwe kopie, co oznaczało, że mogłem skierować dd na najniższy adres i wyodrębnić cały region do pliku tymczasowego. Edytor Vima obsługuje teraz zawartość binarną z wdziękiem, dzięki czemu możesz sprawdzić plik tymczasowy i zmienić go w razie potrzeby.

JonathanH-UK
źródło