Em python eu uso:
repr('test')
para obter a saída:
"'test'"
Quero fazer o mesmo mas no shell para poder armazenar esse valor em uma variável. Como eu posso fazer?
Por exemplo: Se eu executar um comando:
echo $test
Eu recebo a saída:
ghjghj "' bhj ""'' bjhv "''hjuhd
No shell eu quero fazer isso:
test=repr(repr($test))
Responder1
Algo semelhante ao do Python repr
é printf %q
which poderia ser combinado com printf -v
which "imprime" em outra variável em vez de stdout. (embora não seja padrão, é compatível com o printf integrado do bash e zsh):
[prompt] foo=$(cat <<'EOT'
'"'<>\`'"'''()*@@@@$$$$````'''''
EOT
)
[prompt] printf '%q\n' "$foo"
\'\"\'\<\>\\\`\'\"\'\'\'\(\)\*@@@@\$\$\$\$\`\`\`\`\'\'\'\'\'
[prompt] printf -v bar %q "$foo"
Um uso prático disso é quando você deseja passar comandos através de vários ssh (por exemplo, quando você não pode definir o encaminhamento em hosts intermediários com ssh -J
), e até mesmoumo nível de fuga é demais para poder acompanhar (pelo menos para mim):
[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
Porém, tenha cuidado, pois isso printf %q
usará o $'...'
formato quote-escape, que pode não ser suportado pelo shell remoto(embora seja suportado por bash, zsh, etc e supostamente previsto para ser incluído em uma versão futura do padrão POSIX).
Bash e ksh93 também possuem typeset -p
(também utilizável como declare -p
no bash), mas só funciona com variáveis, não com literais:
[prompt] typeset -p foo
declare -- foo="'\"'<>\\\`'\"'''()*@@@@\$\$\$\$\`\`\`\`'''''"
[prompt]
Como alternativa printf %q
, as versões mais recentes do bash também possuem o ${var@Q}
formato de expansão especial:
[bash] echo "${foo@Q}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''