Pythonでは以下を使用します:
repr('test')
出力を取得するには:
"'test'"
同じことをシェルで実行して、この値を変数に格納できるようにしたいのですが、どうすればよいですか?
たとえば、次のコマンドを実行すると:
echo $test
出力は次のようになります:
ghjghj "' bhj ""'' bjhv "''hjuhd
シェルでは次の操作を実行したい:
test=repr(repr($test))
答え1
Python のものと似ているのは、which を which と組み合わせて、stdout ではなく別の変数に「出力」すること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
)や、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}"
''\''"'\''<>\`'\''"'\'''\'''\''()*@@@@$$$$````'\'''\'''\'''\'''\'''