passage dd ignorer | rechercher l'offset en hexadécimal


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

Pourquoi la deuxième commande génère une valeur différente?

Est-il possible de passer l'offset skip | à ddune valeur hexadécimale?

Réponses:


18

Pourquoi la deuxième commande génère une valeur différente?

Pour des raisons historiques, ddconsidère xêtre un opérateur de multiplication. 0x3Est donc évalué à 0.

Est-il possible de passer le décalage de saut de recherche à dd en tant que valeur hexadécimale?

Pas directement, pour autant que je sache. En plus de la multiplication à l'aide de l'opérateur x, vous pouvez suffixer n'importe quel nombre avec bpour signifier "multiplier par 512" (0x200) et avec Kpour signifier "multiplier par 1024" (0x400). Avec GNU dd on peut également utiliser des suffixes M, G, T, P, E, Zet Ypour signifier multiplier par 2 à la puissance 20, 30, 40, 50, 60, 70, 80 ou 90, respectivement, et on peut utiliser supérieure ou inférieure cas sauf pour le bsuffixe. (Il existe de nombreux autres suffixes possibles. Par exemple, EBsignifie «multiplier par 10 18 » et PiB«multiplier par 2 50 ». Voir info coreutils "block size"pour plus d'informations, si vous avez une installation GNU.)

Vous pourriez trouver les arcanes, anachroniques et geek ci-dessus au point d'absurdité. Ne vous inquiétez pas: vous n'êtes pas seul. Heureusement, vous pouvez simplement ignorer tout cela et utiliser à la place la substitution arithmétique de votre shell (bash et d'autres shells compatibles Posix fonctionneront, ainsi que certains shells non Posix). Le shell comprend les nombres hexadécimaux et permet une gamme complète d'opérateurs arithmétiques écrits de la manière normale. Vous avez juste besoin d'entourer l'expression avec $((...)):

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

Notez que $((...))c'est une expansion arithmétique POSIX, elle n'est pas du tout spécifique à bash, vous n'avez pas besoin de l'utiliser bashpour l'utiliser, n'importe quel shell POSIX fera l'affaire. Cependant, notez que dans de nombreux shells, y compris bash, il subit un fractionnement de mots et doit donc être cité.
Stéphane Chazelas

@StephaneChazelas: C'est vrai, ce n'est pas spécifique à bash. Cependant, il n'a pas besoin de devis. (Posix: "L'expression doit être traitée comme si elle était entre guillemets doubles, sauf qu'un guillemet double à l'intérieur de l'expression n'est pas traité spécialement.") S'il y avait une variable dans l'expression et que sa valeur incluait un séparateur, alors ce ne serait pas un nombre valide; mettre des guillemets autour $((...))ne changera rien. Le seul cas où je peux penser où les citations feraient quelque chose est si vous aviez quelque chose comme IFS=4ça, mais cela provoquerait toutes sortes d'autres chaos.
rici

La section que vous citez concerne ce qui se trouve à l'intérieur $((...)). POSIX est clair que l'expansion de $((...))est sujette à la division des mots . Laisser une des extensions commande / arithmétique / variable sans guillemets dans le contexte de la liste est l'opérateur split + glob. Définir IFS = 4 ne causerait pas toutes sortes de problèmes si vous n'utilisez pas l'opérateur split + glob là où il n'est pas nécessaire / souhaité, et définissez IFS chaque fois que vous avez besoin de cet opérateur split + glob.
Stéphane Chazelas

@StephaneChazelas: oui, le résultat numérique est sujet au fractionnement de mots. Mais c'est un entier. Si vous définissez IFSquelque chose qui comprend des chiffres, quelque chose que je ne pense pas avoir fait, alors vous devrez citer. Vraisemblablement, si l'on faisait cela, on serait conscient du besoin, car ce n'est guère quelque chose que l'on est susceptible de faire avec désinvolture. Ou, du moins, ce n'est pas quelque chose que je vais probablement faire, point final. Je ne veux pas parler pour toi.
rici

1
@ogurets: quel shell utilisez-vous? (Veuillez inclure la version).
rici

0

Je sais que c'est un vieux fil de discussion, mais le problème est toujours aussi d'actualité, surtout lorsque des idiots comme moi s'en vont et rappellent et exécutent par inadvertance un `` cp fileA fileB '' de l'historique bash lorsque fileB n'est pas encore enregistré pour git non sauvegardé et contenant plusieurs heures de codage après une nuit blanche: - /

Grâce aux concepts de ce fil, j'ai pu récupérer complètement mon fichier perdu, mais j'ai perdu le mien sur un serveur privé virtuel distant avec un disque de 32 Go et très peu de RAM (exécutant Ubuntu 18.04), et tous mes attemtps utilisant 'grep' comme ci-dessus mourrait rapidement avec une «mémoire insuffisante»

Dans mon cas, c'est hexdump -C /dev/sdX1 | grep 'shortString'ce qui est venu à mon secours. Contrairement à grep, il n'affiche qu'une représentation ASCII très étroite de l'hex, il est donc essentiel de ne rechercher qu'une courte chaîne unique et de garder à l'esprit que même cela pourrait être encapsulé. Une fois qu'il a sorti une adresse hexadécimale où il y avait une correspondance, j'ai pu utiliser 'dd' de la même manière que ci-dessus, sauf que j'ai trouvé qu'il semblait être par défaut à une taille de bloc de 4096, donc je n'ai pas seulement dû convertissez l'adresse en octets hexadécimaux en décimal, mais divisez-la par 4096 pour la mettre à l'échelle en blocs de 4 k pour le paramètre de saut de dd - inutile, si ce nombre est trop grand pour dd, le message d'erreur semble se plaindre d' skip=être invalide plutôt que le nombre qui lui a été transmis .

Félicitations aux personnes qui ont ajouté des conseils sur l'utilisation de bash avec la $((0xabcd))conversion d'obtention facile hexa> déc :-)

Juste mon dernier mot - Dans mon cas, il y avait plusieurs copies du même dossier qui étaient toutes à proximité. Mais en soustrayant l'adresse la plus basse de l'adresse la plus élevée rapportée par hexdump, j'ai pu identifier une région de ~ 5 Mo contenant toutes les copies possibles, ce qui signifiait que je pouvais cibler dd à l'adresse la plus basse et extraire cette région entière dans un fichier temporaire. L'éditeur Vim gère désormais le contenu binaire de manière assez gracieuse afin que vous puissiez ensuite examiner le fichier temporaire et le remodeler si nécessaire.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.