シェルプログラムa、b、cがあり、それぞれが他のコマンドからコマンドを実行しているとしましょう。何らかの理由で、引用符が必要です。例:
a 'b 'c 'echo test'''
したがって、a は b を呼び出し、b は c を呼び出し、c は「エコー テスト」を呼び出します。私の引用が間違って解釈されることはすでにおわかりでしょう。また、a、b、c は system() を呼び出す C プログラムであることに注意してください。
引用符を保持して、それを行う解決策はありますか?
C の準備が整った解決策はありませんが、この場合、引用する文字列を取得し、すべて'
をに置き換えて'\''
、全体を で囲むことをお勧めします'
。
echo test
、喜んで入れて:''
に与えることができます。c
c 'echo test'
次に、その文字列を に渡しますb
。'
上記の文字列にはsが含まれているため、ここで開始します。つまり、 '
+ c '\''echo test'\''
+'
を b: に指定しb 'c '\''echo test'\'''
ます。そこで何が起こるの?b
の引数のいくつかの連結部分を連結しました:
'c ', which becomes just
c `、\'
となり、'
'echo test'
、これはecho test
引用符を取り除いた後です。\'
再び -> '
、そして''
'
これは何もなく、元の文字列の末尾にa があるためにのみ存在します。手動で処理する場合は省略できますが、アルゴリズムで努力する価値はありません。これc 'echo test'
は、前述のアルゴリズムが機能することを示しています。
b 'c '\''echo test'\'''
の引数を取得するために、このプロセスをもう一度実行すると、a
が得られますa 'b '\''c '\''\'\'''\''echo test'\''\'\'''\'''\'''
。
\
s:を 2 倍にする必要がありますsystem("a 'b '\\''c '\\''\\'\\'''\\''echo test'\\''\\'\\'''\\'''\\'''");
。'
開始、終了、および連続するs で上記の最適化を行うと、次のようになります。
b 'c '\''echo test'\'
と
a 'b '\''c '\''\'\'\''echo test'\''\'\'
それぞれ
system("a 'b '\\''c '\\''\\'\\'\\''echo test'\\''\\'\\'");
.
'
または、 なしでスペースと '\' を引用することもできますが、それはおそらくさらにトリッキーです...
私が試してみましょう:
echo test
-> echo\ test
-> c echo\ test
.b c\ echo\\\ test
.a b\ c\\\ echo\\\\\\\ test
.system("a b\\ c\\\\\\ echo\\\\\\\\\\\\\\ test")
。醜い引用ですが、うまくいきます。
でテスト済み
#!/usr/bin/env python
import sys
import subprocess
sp=subprocess.Popen(sys.argv[1], shell=True, stdout=subprocess.PIPE)
for line in sp.stdout:
print "%s> %s" % (sys.argv[0], line),
exit(sp.wait())
としてa
、b
およびc
_
import os
print 1
os.system("a 'b '\\''c '\\''\\'\\'''\\''echo test'\\''\\'\\'''\\'''\\'''")
print 2
os.system("a 'b '\\''c '\\''\\'\\'\\''echo test'\\''\\'\\'")
print 3
os.system("a b\\ c\\\\\\ echo\\\\\\\\\\\\\\ test")
とtest.py
呼ばれる
PATH=.:$PATH python -m test
この場合、Python には C と同じ引用規則があるため、十分なテストです。
内側の引用符をエスケープする必要があります。残念ながら、一重引用符を使用することは実際には不可能です。したがって、二重引用符で囲まれた文字列にはエスケープせずに一重引用符を含めることができるため、すべての外側のレベルに二重引用符を使用し、最も内側の引用符に一重引用符を使用します。したがって、結果は次のようになります。
a "b \"c 'echo test'\""
通過する必要がある各レベルにバックスラッシュを追加する必要があることに注意してください。そのため、" が最後のレベルで使用されている場合は、
a "b \"c \\\"echo test\\\"\""
次のレベルでは 7 つのバックスラッシュなどになります。