シェルで同等の表現

シェルで同等の表現

Pythonでは次のように使用します。

repr('test')

出力を取得します。

"'test'"

私も同じことをしたいのですが、シェルでは値を変数に保存できます。どうですか?

たとえば、次のコマンドを実行すると、次のようになります。

echo $test

私は出力を取得します:

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

シェルでは、次のことをしたいと思います。

test=repr(repr($test))

答え1

Pythonと同様に、reprこれはstdoutの代わりに他の変数に「印刷」することと組み合わせることprintf %qができます。printf -v(標準ではありませんが、bashとzsh printfの組み込み機能がサポートしています):

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

実際の用途の1つは、複数の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(bashのように使用することもできますdeclare -p)、リテラルではなく変数でのみ機能します。

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

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

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

関連情報