En Python uso:
repr('test')
para obtener la salida:
"'test'"
Quiero hacer lo mismo pero en el shell para poder almacenar este valor en una variable. ¿Como lo puedo hacer?
Por ejemplo: si ejecuto un comando:
echo $test
Obtengo el resultado:
ghjghj "' bhj ""'' bjhv "''hjuhd
En shell quiero hacer esto:
test=repr(repr($test))
Respuesta1
Algo similar a Python repr
es printf %q
que podría combinarse con printf -v
cuál "imprime" en otra variable en lugar de la salida estándar. (aunque no es estándar, es compatible con el printf integrado de bash y zsh):
[prompt] foo=$(cat <<'EOT'
'"'<>\`'"'''()*@@@@$$$$````'''''
EOT
)
[prompt] printf '%q\n' "$foo"
\'\"\'\<\>\\\`\'\"\'\'\'\(\)\*@@@@\$\$\$\$\`\`\`\`\'\'\'\'\'
[prompt] printf -v bar %q "$foo"
Un uso práctico de esto es cuando desea pasar comandos a través de múltiples ssh (por ejemplo, cuando no puede configurar el reenvío en hosts intermedios con ssh -J
), e inclusounoEl nivel de escape es demasiado para poder realizar un seguimiento (al menos para mí):
[prompt] cmd='echo "$USER'\''s \$HOME on $HOSTNAME is $HOME"'
[prompt] ssh localhost "$cmd"
luser12's $HOME on kgbvax is /home/luser12
[prompt] printf -v cmd %q "$cmd"
[prompt] ssh localhost ssh localhost "$cmd"
luser12's $HOME on kgbvax is /home/luser12
[prompt] printf -v cmd %q "$cmd"
[prompt] printf -v cmd %q "$cmd"
[prompt] printf -v cmd %q "$cmd"
[prompt] echo "$cmd"
echo\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\"\\\\\\\\\\\\\\\$USER\\\\\\\\\\\\\\\'s\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\$HOME\\\\\\\\\\\\\\\ on\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\$HOSTNAME\\\\\\\\\\\\\\\ is\\\\\\\\\\\\\\\ \\\\\\\\\\\\\\\$HOME\\\\\\\\\\\\\\\"
# OK, we're ready to go
[prompt] ssh localhost ssh localhost ssh localhost ssh localhost ssh localhost "$cmd"
luser12's $HOME on kgbvax is /home/luser12
Sin embargo, tenga en cuenta que printf %q
utilizará el $'...'
formato de escape de comillas, que puede no ser compatible con el shell remoto.(aunque es compatible con bash, zsh, etc. y supuestamente está previsto que se incluya en una versión futura del estándar POSIX).
Bash y ksh93 también tienen typeset -p
(también utilizable como declare -p
en bash), pero solo funciona con variables, no con literales:
[prompt] typeset -p foo
declare -- foo="'\"'<>\\\`'\"'''()*@@@@\$\$\$\$\`\`\`\`'''''"
[prompt]
Como alternativa a printf %q
, las versiones más nuevas de bash también tienen la ${var@Q}
forma de expansión especial:
[bash] echo "${foo@Q}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''