2

Djangoを標準のWSGI/Apachehttpdコンボで実行しています。

シェルでコードを実行した場合とブラウザーからコードを実行した場合では、ファイルの出力が異なることに気付きました。私は他のすべてを分離しましたが、それでも同じ問題が発生しています。

コードは次のとおりです。

def test_antiword(filename):
    import subprocess
    with open(filename, 'w') as writefile:
        subprocess.Popen(["antiword", '/tmp/test.doc'], stdout=writefile)
    p = subprocess.Popen(["antiword", '/tmp/test.doc'], stdout=subprocess.PIPE)
    out, _ = p.communicate()
    ords = []
    for kk in out:
        ords.append(ord(kk))
    return out, ords

def test_antiword_view(request):
    import HttpResponse
    return HttpResponse(repr(test_antiword('/tmp/web.txt')))

ブラウザでURLを開くと、次のように出力されます。

('\ n "私は良い日を言いました。良い日です!"とSh \ xe9rlo \ xe7k H \ xf8lme\xa3を叫びました。 、32、115、97、105、100、32、103、111、111、100、32、100、97、121、32、115、105、114、46、32、71、111、111、100、32 、100、97、121、33、34、32、115、104、111、117、116、101、100、32、83、104、233、114、108、111、231、107、32、72、248 、108、109、101、163、46、10、10、32、32、32、32、32、32、32、32、32、32、32、32、32、34、87、104、121、32 、110、111、116、32、90、111、105、100、98、101、114、103、63、34、32、113、117、101、114、105、101、100、32、90、111 、105、100、98、101、114、103、46、10])

これは、test_antiword('/tmp/shell.txt')inehteshellを呼び出したときの対応する出力です。

('\ n \ xe2 \ x80 \ x9cいい日だと言った。いい日だ!\ xe2 \ x80\x9dはSh\xc3 \ xa9rlo \ xc3 \ xa7k H \ xc3 \ xb8lme \ xc2\xa3と叫んだ。\n\ n \ xe2 \ x80 \ x9cなぜゾイドバーグではないのですか?\ xe2 \ x80 \x9dはゾイドバーグに問い合わせました。\n'、[10、226、128、156、73、32、115、97、105、100、32、103、111、111、100 、32、100、97、121、32、115、105、114、46、32、71、111、111、100、32、100、97、121、33、226、128、157、32、115、104 、111、117、116、101、100、32、83、104、195、169、114、108、111、195、167、107、32、72、195、184、108、109、101、194、163 、46、10、10、32、32、32、32、32、32、32、32、32、32、32、32、32、226、128、156、87、104、121、32、110、111 、116、32、90、111、105、100、98、101、114、103、63、226、128、157、32、113、117、101、114、105、101、100、32、90、111 、105、100、98、101、114、103、46、10])

ご覧のとおり、出力は大きく異なります。一つには、シェル出力は元のファイルにあった空白を維持します。Webバージョンでは失われます。

コードからわかるように、ドキュメントもファイルに出力します。生成される出力は次のとおりです。

web.txt

"I said good day sir. Good day!" shouted Sh?rlo?k H?lme?.

             "Why not Zoidberg?" queried Zoidberg.

shell.txt

“I said good day sir. Good day!” shouted Shérloçk Hølme£.

             “Why not Zoidberg?” queried Zoidberg.

Webバージョンでは、文字は認識されず、エンコーディングはfileISO-8859として識別されます。シェルバージョンでは、文字は正しく表示され、エンコーディングはfileUTF-8として識別されます。

なぜこれが起こっているのか途方に暮れています。確認したところ、両方のプロセスで同じバージョンのアンチワードが使用されています。さらに、両方が同じpythonモジュールファイルを使用していることを確認しましたsubprocess。どちらの場合も使用されているPythonのバージョンも完全に一致します。

誰かが何が起こっているのか説明できますか?

4

1 に答える 1

4

違いは、環境変数が原因である可能性があります。マニュアルページによると:

Antiwordは、環境変数LC_ALLLC_CTYPEおよびLANG(この順序で)を使用して現在のロケールを取得し、この情報を使用してデフォルトのマッピングファイルを選択します。

シェルから実行すると、シェルはUTF-8ロケールになりますが、Djangoから実行すると、別のロケールになり、Unicode文字を適切に変換できなくなります。次のようにサブプロセスを実行する場合は、UTF-8ロケールに切り替えてみてください。

new_env = dict(os.environ)  # Copy current environment
new_env['LANG'] = 'en_US.UTF-8'
p = subprocess.Popen(..., env=new_env)
于 2012-11-15T19:02:05.130 に答える