web-dev-qa-db-ja.com

シェルで同等のrepr

python私は使用します:

repr('test')

出力を取得するため:

"'test'"

同じことをしたいのですが、シェルでこの値を変数に格納できるようにします。どのようにできるのか?

例:コマンドを実行した場合:

echo $test

出力を取得します:

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

シェルで私はこれをしたい:

test=repr(repr($test))
2

Pythonのreprに似たものはprintf %qであり、これをprintf -vと組み合わせると、stdoutではなく別の変数に「出力」されます。 (非標準ですが、bashおよびzshの組み込みのprintfでサポートされています):

[Prompt] foo=$(cat <<'EOT'
'"'<>\`'"'''()*@@@@$$$$````'''''
EOT
)
[Prompt] printf '%q\n' "$foo"
\'\"\'\<\>\\\`\'\"\'\'\'\(\)\*@@@@\$\$\$\$\`\`\`\`\'\'\'\'\'
[Prompt] printf -v bar %q "$foo"

これの実用的な使用法の1つは、複数のsshを介してコマンドを渡したい場合(たとえば、ssh -Jを使用して中間ホストで転送を設定できない場合)であり、oneレベルのエスケープが多すぎて(少なくとも私にとっては)追跡できる:

[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

Bashとksh93にはtypeset -p(bashではdeclare -pとしても使用可能)もありますが、リテラルではなく、変数でのみ機能します。

[Prompt] typeset -p foo
declare -- foo="'\"'<>\\\`'\"'''()*@@@@\$\$\$\$\`\`\`\`'''''"
[Prompt]

printf %qの代わりに、新しいバージョンのbashにも${var@Q}特別な拡張形式があります。

[bash] echo "${foo@Q}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''
4
pizdelect