Bash

外殼中的 repr 等效項

  • October 3, 2020

在python中我使用:

repr('test')

獲取輸出:

"'test'"

我想做同樣的事情,但在 shell 中能夠將此值儲存在變數中。我能怎麼做?

例如:如果我執行一個命令:

echo $test

我得到輸出:

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

在外殼中我想這樣做:

test=repr(repr($test))

類似於 Python 的東西可以與repr哪個“列印”到另一個變數而不是標準輸出相結合。(雖然是非標準的,但它在 bash 和 zsh 的內置 printf 中得到支持):printf %q``printf -v

[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將使用$'...'quote-escape 格式,遠端shell 可能不支持該格式(儘管它受到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}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''

引用自:https://unix.stackexchange.com/questions/572722