Pregunta

Estoy buscando el equivalente de un urlencode para salida de terminal: necesito asegurarme de que los caracteres basura que (puedo) imprimir desde una fuente externa no terminen haciendo cosas extrañas en mi terminal, por lo que una función preempaquetada para escapar de secuencias de caracteres especiales sería ideal.

Estoy trabajando en Python, pero cualquier cosa que pueda traducir fácilmente también funciona. TIA!

¿Fue útil?

Solución

$ ./command | cat -v

$ cat --help | grep nonprinting
-v, --show-nonprinting   use ^ and M- notation, except for LFD and TAB

Esto es lo mismo en py3k basado en 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))

Ejemplo:

$ 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 

Imprime:

Files cat-v.out and python.out are identical

Otros consejos

Desafortunadamente " salida de terminal " es un criterio muy poco definido para el filtrado (consulte pregunta 418176 ) Sugeriría simplemente incluir en la lista blanca los caracteres que desea permitir (que sería la mayor parte de string.printable), y reemplazar todos los demás con el formato de escape que desee (\ FF,% FF, etc.), o incluso simplemente eliminarlos.

Si registro o imprimo resultados de depuración, generalmente uso repr () para obtener una versión imprimible inofensiva de un objeto, incluidas las cadenas. Esto puede o no ser lo que querías; El método cat --show-nonprinting que otros han usado en otras respuestas es mejor para muchas salidas de varias líneas.

x = get_weird_data()
print repr(x)

Podrías canalizarlo a través de cadenas

./command | strings

Esto eliminará los caracteres que no sean cadenas

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top