次のコマンドを実行したいと思います。
$ sh -c 'exec python -c "print('$1$2MyString')"'
望ましい結果として'$1$2MyString'
。
ただし、コマンドを実行すると、次の結果が表示されます。
Traceback (most recent call last):
File "<string>", line 1, in <module>
NameError: name 'MysString' is not defined
私が知っている限り、3番目のレベルの引用符を追加すると、実際にコマンドが2つの部分に分割され、シェルは$1$2MyString
外部引用符を見て既知の値を変更しようとします。
一重引用符をエスケープすると
$ sh -c 'exec python -c "print(\'$1$2MyString\')"'
次のエラーが発生します。
sh: 1: Syntax error: "(" unexpected
本質的に私の質問は:上記の印刷機能に文字列リテラルを導入する方法はありますか?
答え1
一重引用符で囲まれた文字列内では、一重引用符をエスケープできません。たとえば、以下は不完全な行です。
echo 'boy\'s game' # Wrong!
>
ただし、さまざまな種類の引用符で囲まれた文字列を連結できます。
echo "boy's"' game' # Right
boy's game
したがって、引用文"'"
などを引用できます。
sh -c 'exec python -c "print('"'"'$1$2MyString'"'"')"'
# ^-. . . . . . . . . . -^ ^-. . . . . -^ ^--^
# ^-^ ^-^
この出力は、呼び出しによって評価が実行されるためMyString
に発生します。リテラルとして使用するには、一重引用符で囲んで明示的に保護する必要があります。$1$2
sh
$1$2MyString
sh
sh -c 'exec python -c '"'"'print("$1$2MyString")'"'"
# ^-. . . . . . .-^ ^-. . . . . . . . . .-^
答え2
引用符は入れ子にされません(コマンドの置換を除く)。一重引用符で囲まれた文字列内では、二重引用符は通常の文字であり、引用符としては機能しません。その逆。
Pythonに引数を渡したい場合は、print('$1$2MyString')
必要なエスケープを実行できますが、文字列に一重引用符とドル記号の両方が含まれているため、厄介です。つまり、エスケープしなくなった場合は、単一引用符と二重引用符の両方を使用できません。文字列自体にも必要な2番目のレベルの参照を考慮することは言うまでもありません。
または、環境を介して文字列を渡すなどの操作を実行しますsh
。
code="print('\$1\$2MyString')" # or
code='print('\''$1$2MyString'\'')'
code=$code sh -c 'exec python -c "$code"'
または、出力を'$1$2MyString'
一重引用符で表示する必要がある場合は、Pythonコードは次のようになりますprint("'$1$2MyString'")
。
code='print("'\''$1$2MyString'\''")'
code=$code sh -c 'exec python -c "$code"'
Pythonコードをファイルに入れる方が簡単かもしれません。