Un environnement de type shell pour le traitement binaire

15

Cette question m'est venue plusieurs fois auparavant, maintenant en réponse à la question Boucle à travers des morceaux de données binaires de stdin dans Bash Answers donnée dans /programming/993434/what-language-is-to-binary -as-perl-is-to-text n'étaient pas non plus satisfaisants.

Je recherche un environnement de script adapté spécifiquement pour gérer les E / S avec des fichiers binaires. Je sais que je peux utiliser l'un des langages de programmation à part entière (c / Python / ...) mais ils ont une énorme charge d'initialisation et de codage (allocation et fread / fwrite en c, chaînes de bits en Python ...) sans oublier ils sont moins adaptés à l'écriture de scripts (appel à d'autres applications depuis celui-ci). Perl n'est pas meilleur avec ses unpackfonctions, son fonctionnement orienté chaîne et sa syntaxe maladroite.

Quelque chose comme od, mais comme une langue.

Ce que j'attends:

  1. définir ou modifier l'endianité avec un seul commutateur / commande.
  2. spécification simple du type demandé (quelque chose comme étendre bash read varavec int32 var, float varetc.).
  3. gestion du binaire à travers des tuyaux, saut du nombre spécifié d'octets.
  4. contrôle de flux de script standard (pour / if / ...) auquel nous sommes habitués.

J'aimerais traiter des données brutes (photographie, données scientifiques, formats inconnus et mal documentés) avec la même facilité et perspicacité que vous obtenez lors de l'inspection de fichiers ASCII. J'utilise cmaintenant, mais ce n'est pas optimal pour les scripts ad hoc et ne peut pas être interactif.

Est-ce que quelqu'un connaît un outil comme ça? Aucun logiciel GUI clicky, s'il vous plaît, il doit fonctionner sur ssh, à partir d'autres scripts et ainsi de suite. "N'existe pas" est une réponse acceptable mais déprimante.

orion
la source
2
Cela n'enlève pas la douleur du temps de démarrage, mais je trouve les octets de Python 3.3, ainsi que le plumbum très réalisables: chain = ls["-a"] | grep["-v", "\\.py"] | wc["-l"]; chain()avez-vous regardé cela?
Anthon
Vous pouvez prendre le code C que vous avez maintenant et le transformer en un ensemble d'outils de ligne de commande que vous pourriez utiliser dans un script bash. Bien que vous ne puissiez pas mettre le binaire dans une variable shell, vous pouvez le cacher dans des canaux nommés ('fifo'); leur contenu est conservé en mémoire jusqu'à ce que vous souhaitiez les lire.
goldilocks
1
Il y a une faille sérieuse dans votre raisonnement WRT python et perl, BTW. Bien que les outils de ligne de commande individuels soient compilés, les scripts shell ne le sont pas et impliquent beaucoup de forking (si vous voulez cher, c'est le forking). Votre discussion, autre question, etc., implique que vous iriez bien avec bash ici s'il pouvait gérer le binaire. Les scripts Python et perl sont tous deux précompilés. Si vous comparez un script python ou perl raisonnablement complexe à un script bash parallèle, le perl ou le python sera plus rapide d'un ordre de grandeur . Si vous ne me croyez pas, vous êtes invité à rechercher sur le Web des preuves du contraire.
goldilocks
Je ne cherche pas un outil qui tourne vite, je cherche quelque chose que je peux coder rapidement. Par exemple, si j'ai un programme étrange qui génère un int binaire pour la taille du tableau des structures (int, float, float) qui le suivent, j'aimerais lire rapidement la taille du tableau et boucler sur le tableau, en calculant éventuellement certains cumulatif ou maximum de certains composants, ou imprimez simplement un composant en tant que colonne ascii pour le traitement gnuplot. Anthon: merci, je ne le savais pas, ce sera utile. Bouchons d'or: j'essaye d'éviter cela mais je peux juste écrire mon propre outil à la fin :)
orion
2
On dirait que vous avez besoin d'un tutoriel sur l'utilisation perlde unpack(ᵔᴥᵔ)
Stéphane Chazelas

Réponses:

2

J'ai le même problème que vous depuis des années.

Pour des utilisations simples et non interactives, j'aime utiliser l'éditeur de blocs binaires BBE . BBE est au binaire comme SED au texte, y compris sa syntaxe archaïque et sa simplicité, cependant, il a beaucoup de fonctionnalités manquantes de ce dont j'ai souvent besoin, donc je dois le combiner avec d'autres outils. BBE n'est donc qu'une solution partielle. Notez également que BBE n'a eu aucune mise à jour ou amélioration depuis des années.

Bien sûr, on peut utiliser xxdavant et xxd -raprès la modification des données avec des outils basés sur du texte, mais cela ne fonctionnera pas lorsque les données en question sont volumineuses et qu'un accès aléatoire est requis, par exemple lors du traitement des blocs de périphériques.

(Remarque: pour Windows, il existe au moins le langage de script WinHex propriétaire et coûteux, mais cela ne nous mènera nulle part.)

Pour les éditions binaires plus compliquées, je retombe généralement sur Python, même s'il est parfois trop lent pour les gros fichiers, ce qui est son principal inconvénient. J'espère Pyston (Python utilisant LLVM pour compiler en code machine optimisé) arrivera un jour à mûrir suffisamment pour être utilisable, ou mieux encore, quelqu'un concevra et implémentera un langage de script de traitement binaire gratuit, compact, rapide et polyvalent, pour lequel AFAIK n'existe pas U * IX comme des systèmes encore.

MISE À JOUR

Il se trouve que j'utilise également l'assembleur plat homebrew, open source Intel x86 assembler , ou fasm pour faire court, qui est devenu bien plus qu'un simple assembleur.

Il possède un puissant préprocesseur de macro basé sur des blocs de texte (lui-même un langage complet) avec une syntaxe dans la tradition du langage de macro du borland turbo assembler, mais beaucoup plus avancé.

En outre, il dispose d'un langage de manipulation de données, qui permet d'inclure des fichiers arbitraires binaires, d'effectuer toutes sortes de manipulations binaires et arithmétiques sur celui-ci (entier uniquement) au "moment de la compilation" et d'écrire le résultat dans un fichier de sortie. Ce langage de manipulation de données a des structures de contrôle et est également complet.

Il est beaucoup plus facile à utiliser que d'écrire un programme qui fait des manipulations binaires en C et probablement même en python. De plus, il se charge à une vitesse aveuglante, car il s'agit d'un exécutable de petite taille sans presque aucune dépendance externe (il existe 2 versions: soit il ne nécessite que libc, soit il peut s'exécuter en tant qu'exécutable statique directement sur le noyau Linux ABI).

Il a des bords de collerette, comme

  1. ne prend pas en charge la simultanéité

  2. étant en écriture dans un assemblage x86 32 bits (fonctionne sur x86_64 cependant), vous avez probablement besoin de qemu ou d'un émulateur similaire si vous voulez l'exécuter sur autre chose que x86 ou x86_64

  3. son puissant langage de préprocesseur de macros est complet, cela signifie que vous feriez mieux d'avoir une certaine expérience avec des langages comme Lisp, Haskell, XSLT, ou probablement M4 serait le meilleur choix.

  4. toutes les données qui doivent être écrites dans le fichier de sortie sont exécutées dans un tampon "plat" en mémoire, et ce tampon peut augmenter mais ne pas rétrécir jusqu'à ce que le fichier de sortie ait été écrit et que fasm soit terminé. Cela signifie que l'on ne peut générer des fichiers au maximum aussi volumineux que la mémoire principale restante dans une seule exécution de fasm.

  5. les données ne peuvent être écrites que dans un seul fichier de sortie pour chaque série de fasm

  6. oui, c'est un homebrew, vraiment très soigné et intelligent

Franki
la source
2

Vous n'avez pas nécessairement à "faire la paix" avec le déballage de Perl ... l'une des grandes choses à propos de perl est comment vous pouvez abuser de l'analyseur et de la table des symboles pour créer votre propre langue, dans un package personnalisé.

Est-ce essentiellement ce que vous recherchez?

use MyBinLib;
my $struct= struct(
  pack => 8,
  size => 400,
  fields => [int32('foo','bar','baz'), float32('x1','x2','x3','x4'), int8, int8, int16('z')]
);
while (my $rec= $struct->read(<STDIN>)) {
  printf "x1 = %d, x2 = $d\n", $rec->x1, $rec->x2;
}

L'exercice consiste alors à apprendre suffisamment de perl pour écrire le package MyBinLib. Demandez dans un forum Perl et les gens seront probablement ravis de vous aider.

M Conrad
la source
1

Avez-vous rencontré des beavmacros mais je n'ai pas trouvé de script,

apt-cache show beav extrait :

Avec beav, vous pouvez modifier un fichier en HEX, ASCII, EBCDIC, OCTAL, DECIMAL et BINARY. Vous pouvez afficher mais pas modifier les données en mode FLOAT. Vous pouvez rechercher ou rechercher et remplacer dans l'un de ces modes. Les données peuvent être affichées au format BYTE, WORD ou DOUBLE WORD. Lors de l'affichage des MOTS ou des MOTS DOUBLES, les données peuvent être affichées dans l'ordre des octets d'INTEL ou de MOTOROLA. Des données de n'importe quelle longueur peuvent être insérées à tout moment dans le fichier. La source de ces données peut être le clavier, un autre tampon ou un fichier. Toutes les données affichées peuvent être envoyées à une imprimante dans le format affiché. Les fichiers plus volumineux que la mémoire peuvent être traités.

Ensuite, il y a xxdce qui convertit en / du mode d'affichage binaire / ascii et pourrait être combiné avec sedou vi, mais n'a pas la fonction d'échange d'octets.

X Tian
la source
0

Vous pouvez toujours aller chercher l'or et descendre dans C ou ASM. Si vous travaillez avec du binaire brut, faites-le rebondir directement sur le registre. Vous êtes «déjà là».

Brad
la source