В питоне я использую:
repr('test')
для получения вывода:
"'test'"
Я хочу сделать то же самое, но в оболочке, чтобы иметь возможность сохранить это значение в переменной. Как мне это сделать?
Например: Если я выполню команду:
echo $test
Я получаю вывод:
ghjghj "' bhj ""'' bjhv "''hjuhd
В оболочке я хочу сделать это:
test=repr(repr($test))
решение1
repr
Что-то похожее на функцию Python, printf %q
which можно объединить с printf -v
which «выводит» в другую переменную вместо stdout. (хотя это нестандартно, но поддерживается встроенной функцией printf из bash и zsh):
[prompt] foo=$(cat <<'EOT'
'"'<>\`'"'''()*@@@@$$$$````'''''
EOT
)
[prompt] printf '%q\n' "$foo"
\'\"\'\<\>\\\`\'\"\'\'\'\(\)\*@@@@\$\$\$\$\`\`\`\`\'\'\'\'\'
[prompt] printf -v bar %q "$foo"
Одним из практических применений этого является ситуация, когда вы хотите передавать команды через несколько SSH (например, когда вы не можете настроить переадресацию на промежуточных хостах с помощью ssh -J
), и дажеодинУровень побега слишком велик, чтобы за ним можно было уследить (по крайней мере, для меня):
[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
Однако будьте осторожны, поскольку при этом printf %q
будет использоваться $'...'
формат экранирования кавычек, который может не поддерживаться удаленной оболочкой.(хотя он поддерживается bash, zsh и т. д. и предположительно должен быть включен в будущую версию стандарта POSIX).
В Bash и ksh93 он также есть typeset -p
(также применим как declare -p
в Bash), но он работает только с переменными, а не с литералами:
[prompt] typeset -p foo
declare -- foo="'\"'<>\\\`'\"'''()*@@@@\$\$\$\$\`\`\`\`'''''"
[prompt]
В качестве альтернативы printf %q
в более новых версиях bash также имеется ${var@Q}
специальная форма расширения:
[bash] echo "${foo@Q}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''