Fonction d'échappement sécurisée pour la sortie du terminal
Question
Je recherche l'équivalent d'un urlencode pour sortie du terminal - Je dois m'assurer que les caractères illisibles que j'imprime depuis une source externe ne finissent pas par faire des choses géniales sur mon terminal, aussi une fonction préemballée pour échapper à des séquences de caractères spéciaux serait idéale.
Je travaille en Python, mais tout ce que je peux facilement traduire fonctionne aussi. TIA!
La solution
$ ./command | cat -v $ cat --help | grep nonprinting -v, --show-nonprinting use ^ and M- notation, except for LFD and TAB
Voici la même chose dans py3k, basé sur android / cat.c :
#!/usr/bin/env python3
"""Emulate `cat -v` behaviour.
use ^ and M- notation, except for LFD and TAB
NOTE: python exits on ^Z in stdin on Windows
NOTE: newlines handling skewed towards interactive terminal.
Particularly, applying the conversion twice might *not* be a no-op
"""
import fileinput, sys
def escape(bytes):
for b in bytes:
assert 0 <= b < 0x100
if b in (0x09, 0x0a): # '\t\n'
yield b
continue
if b > 0x7f: # not ascii
yield 0x4d # 'M'
yield 0x2d # '-'
b &= 0x7f
if b < 0x20: # control char
yield 0x5e # '^'
b |= 0x40
elif b == 0x7f:
yield 0x5e # '^'
yield 0x3f # '?'
continue
yield b
if __name__ == '__main__':
write_bytes = sys.stdout.buffer.write
for bytes in fileinput.input(mode="rb"):
write_bytes(escape(bytes))
Exemple:
$ perl -e"print map chr,0..0xff" > bytes.bin $ cat -v bytes.bin > cat-v.out $ python30 cat-v.py bytes.bin > python.out $ diff -s cat-v.out python.out
Il imprime:
Files cat-v.out and python.out are identical
Autres conseils
Malheureusement, "sortie du terminal". est un critère de filtrage très mal défini (voir question 418176 ). Je suggérerais simplement de mettre en liste blanche les caractères que vous voulez autoriser (ce qui serait plus de string.printable), et de remplacer tous les autres par le format échappé que vous aimez (\ FF,% FF, etc.), ou même de les supprimer.
Si vous enregistrez ou imprimez les résultats du débogage, j’utilise habituellement repr ()
pour obtenir une version sans danger imprimable d’un objet, y compris des chaînes. Cela peut être ou ne pas être ce que tu voulais; la méthode cat --show-nonprinting
que d'autres ont utilisée dans d'autres réponses est préférable pour de nombreuses sorties multi-lignes.
x = get_weird_data()
print repr(x)
Vous pouvez le diriger à travers des chaînes
./command | strings
Ceci supprimera les caractères non-chaînes