シェルにおける repr の同等物

シェルにおける repr の同等物

Pythonでは以下を使用します:

repr('test')

出力を取得するには:

"'test'"

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

たとえば、次のコマンドを実行すると:

echo $test

出力は次のようになります:

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

シェルでは次の操作を実行したい:

test=repr(repr($test))

答え1

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

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

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

[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(bash と同様に使用可能declare -p) がありますが、これは変数でのみ機能し、リテラルでは機能しません。

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

の代わりとしてprintf %q、新しいバージョンの bashには、次${var@Q}の特殊な展開形式もあります。

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

関連情報