passando dd skip | cerca offset come esadecimale


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

Perché il secondo comando genera un valore diverso?

È possibile passare l'offset skip | seek ddcome valore esadecimale?

Risposte:


18

Perché il secondo comando genera un valore diverso?

Per motivi storici, ddconsidera xun operatore di moltiplicazione. Quindi 0x3viene valutato come 0.

È possibile passare l'offset skip | seek a dd come valore esadecimale?

Non direttamente, per quanto ne so. Oltre alla moltiplicazione mediante l'operatore x, è possibile aggiungere un numero qualsiasi con il bsignificato di "moltiplicare per 512" (0x200) e con il Ksignificato di "moltiplicare per 1024" (0x400). Con GNU dd è anche possibile utilizzare suffissi M, G, T, P, E, Ze Yper significare moltiplicare per 2 alla potenza di 20, 30, 40, 50, 60, 70, 80 o 90, rispettivamente, ed è possibile utilizzare superiore o abbassare caso eccetto per il bsuffisso. (Esistono molti altri suffissi possibili. Ad esempio, EBsignifica "moltiplicare per 10 18 " e PiBsignifica "moltiplicare per 2 50 ". Per info coreutils "block size"ulteriori informazioni, vedere se si dispone di un'installazione GNU.)

Potresti trovare quanto sopra arcano, anacronistico e geek al punto di assurdità. Non preoccuparti: non sei solo. Fortunatamente, puoi semplicemente ignorare tutto e utilizzare invece la sostituzione aritmetica della shell (bash e altre shell conformi a Posix funzioneranno, così come alcune shell non Posix). La shell comprende numeri esadecimali e consente una gamma completa di operatori aritmetici scritti in modo normale. Devi solo circondare l'espressione con $((...)):

# dd if=2013-Aug-uptime.csv bs=1 count=$((0x2B * 1024)) skip=$((0x37))

Nota che $((...))è l'espansione aritmetica di POSIX, non è affatto specifica per bash, non devi usarla bashper usarla, qualsiasi shell POSIX lo farà. Tuttavia, si noti che in molte conchiglie comprese bash, subisce la suddivisione delle parole, quindi dovrebbe essere citato.
Stéphane Chazelas il

@StephaneChazelas: È vero, non è specifico per la bash. Tuttavia, non ha bisogno di virgolette. (Posix: "L'espressione deve essere trattata come se fosse tra virgolette doppie, tranne per il fatto che una doppia virgoletta all'interno dell'espressione non è trattata in modo speciale.") Se nell'espressione fosse presente una variabile e il suo valore includesse un separatore, quindi non sarebbe un numero valido; mettere le virgolette intorno al $((...))non cambierà nulla. L'unico caso in cui riesco a pensare a dove le virgolette farebbero qualsiasi cosa è se tu avessi qualcosa del genere IFS=4ma questo causerebbe ogni sorta di altro caos.
rici,

La sezione che citi riguarda ciò che c'è dentro $((...)). POSIX è chiaro che l'espansione di $((...))è soggetta alla divisione delle parole . Lasciare uno qualsiasi dei comandi / aritmetica / espansioni variabili non quotati nel contesto dell'elenco è l'operatore split + glob. L'impostazione di IFS = 4 non causerebbe tutti i tipi di problemi se non si utilizza l'operatore split + glob dove non è necessario / desiderato e si imposta IFS ogni volta che è necessario l'operatore split + glob.
Stéphane Chazelas il

@StephaneChazelas: sì, il risultato numerico è soggetto a suddivisione in parole. Ma è un numero intero. Se hai impostato IFSqualcosa che include cifre, qualcosa che non credo di aver mai fatto, allora dovresti citare. Presumibilmente, se lo facessimo, si sarebbe consapevoli della necessità, dal momento che difficilmente si può fare casualmente. O almeno non è una cosa che probabilmente farò, punto. Non intendo parlare per te.
rici,

1
@ogurets: quale shell stai usando? (Includi la versione).
rici,

0

So che questo è un vecchio thread, ma il problema è ancora più risolutivo che mai, soprattutto quando idioti come me vanno e inavvertitamente ricordano ed escogitano un 'cp ​​fileA fileB' dalla storia di bash quando fileB non è ancora registrato per non essere supportato su, e contenente diverse ore di codifica dopo una notte: - /

Grazie ai concetti di questo thread sono stato in grado di recuperare completamente il mio file perso, tuttavia ho perso il mio su un server privato virtuale remoto con un disco da 32 GB e pochissima RAM (con Ubuntu 18.04) e tutti i miei tentativi usando 'grep' come sopra morirebbe rapidamente con 'memoria insufficiente'

Nel mio caso fu quello hexdump -C /dev/sdX1 | grep 'shortString'che mi venne in soccorso. A differenza di grep, mostra solo una rappresentazione ASCII molto strana dell'esagono, quindi è vitale cercare solo una breve stringa unica e tenere presente che anche quello potrebbe essere avvolto. Una volta che aveva emesso un indirizzo esadecimale in cui c'era una corrispondenza, sono stato in grado di usare 'dd' in un modo simile a quello sopra, tranne per il fatto che ho trovato che l'impostazione predefinita era una dimensione del blocco di 4096, quindi non dovevo solo converte l'indirizzo dei byte esadecimali in decimale ma dividerlo per 4096 per ridimensionarlo a 4k blocchi per il parametro skip di dd - inutilmente, se questo numero è troppo grande per dd il messaggio di errore sembra lamentarsi di skip=essere non valido piuttosto che il numero passato ad esso .

Complimenti alle persone che hanno aggiunto suggerimenti sull'uso di bash con la $((0xabcd))conversione hex-> dec di eastaty obtaion :-)

Solo la mia ultima parola: nel mio caso c'erano diverse copie dello stesso file che erano tutte nelle immediate vicinanze. Ma sottraendo l'indirizzo più basso dall'indirizzo più alto riportato da hexdump sono stato in grado di identificare una regione di ~ 5 MB contenente tutte le copie possibili, il che significava che potevo indirizzare dd con l'indirizzo più basso ed estrarre l'intera regione in un file temporaneo. L'editor Vim ora gestisce il contenuto binario in modo abbastanza grazioso in modo da poter esaminare il file temporaneo e rimodellarlo secondo necessità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.