Al iterar sobre un bytes
valor, obtienes números enteros; estos se convierten trivialmente a notación hexadecimal:
def convert(value: bytes):
return ''.join([f'\\x{b:02x}' for b in value])
Tenga en cuenta que esto produce una cadena con barras invertidas literales, x
caracteres y dígitos hexadecimales . Ya no es un bytes
valor.
Demostración:
>>> print(convert(b'\x01\x02\x41'))
\x01\x02\x41
Solo para asegurarse, no necesita preocuparse por los bytes
valor . El repr()
representación de un bytes
El objeto siempre usará caracteres ASCII cuando el valor del byte sea el de un punto de código ASCII imprimible. Eso no significa que el valor haya cambiado. b'\x01\x02\x41'
es igual a b'\x01\x02A'
. El protocolo Redis no sabe nada sobre \x<HH>
secuencias de escape, así que no intentes enviar la cadena anterior por el cable.
Las secuencias de escape que produce son secuencias de cadenas de shell bash , y al igual que las cadenas de Python, no tiene que usar escapes . Como en Python, para Bash las cadenas "\x01\x02A"
y "\x01\x02\x41"
tienen valores iguales. Solo tienen sentido cuando pasa la clave y las cadenas de valor en la línea de comando, no en un archivo de texto que canaliza a redis-cli
.
Además, tenga en cuenta que redis-cli --pipe
el comando toma entrada de protocolo Redis sin procesar , no la sintaxis de comandos de Redis, consulte Inserción masiva de Redis documentación. Este protocolo no usa \xhh
secuencias, ya que no utiliza la notación shell.
En su lugar, use la siguiente función para generar SET
sin procesar comandos:
def raw_protocol(cmd: str, *args: bytes):
return b'\r\n'.join([
f'*{len(args) + 1}\r\n${len(cmd)}\r\n{cmd}'.encode(),
*(bv for a in args for bv in (b'$%d' % len(a), a)),
b''
])
Para un SET
comando, use raw_protocol('SET', keybytes, valuebytes)
y escriba los datos binarios que esto produce en un archivo abierto en modo binario.