эквивалент repr в оболочке

эквивалент repr в оболочке

В питоне я использую:

repr('test')

для получения вывода:

"'test'"

Я хочу сделать то же самое, но в оболочке, чтобы иметь возможность сохранить это значение в переменной. Как мне это сделать?

Например: Если я выполню команду:

echo $test

Я получаю вывод:

ghjghj "' bhj ""'' bjhv "''hjuhd

В оболочке я хочу сделать это:

test=repr(repr($test))

решение1

reprЧто-то похожее на функцию Python, printf %qwhich можно объединить с printf -vwhich «выводит» в другую переменную вместо 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}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''

Связанный контент