web-dev-qa-db-ja.com

Popen.communicate()が 'hi'ではなくb'hi \ n 'を返すのはなぜですか?

誰かが私が望む結果「hi」の前に文字「b」を付け、その後に改行を付ける理由を説明できますか?

私はPython 3.を使用しています

>>> import subprocess
>>> print(subprocess.Popen("echo hi", Shell=True,
                           stdout=subprocess.PIPE).communicate()[0])
b'hi\n'

この余分な 'b'は、python 2.7で実行すると表示されません。

55
imagineerThat

Echoコマンドはデフォルトで改行文字を返します

これと比較してください:

print(subprocess.Popen("echo -n hi", \
    Shell=True, stdout=subprocess.PIPE).communicate()[0])

文字列の前のbについては、それがPython = 2.6+

http://docs.python.org/3/reference/lexical_analysis.html#literals

10
Necrolyte2

bは、持っているものが bytes であることを示します。これは、Unicode文字の文字列ではなく、バイトのバイナリシーケンスです。サブプロセスは文字ではなく出力バイトを使用するため、communicate()が返します。

bytes型は直接print() ableではないため、reprbytesが表示されています。サブプロセスから受け取ったバイトのエンコードがわかっている場合は、decode()を使用して印刷可能なstrに変換できます。

_>>> print(b'hi\n'.decode('ascii'))
hi
_

もちろん、この特定の例は、サブプロセスからASCIIを実際に受信している場合にのみ機能します。ASCIIでない場合は、例外が発生します。

_>>> print(b'\xff'.decode('ascii'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0…
_

改行は_echo hi_が出力するものの一部です。 echoの仕事は、渡したパラメーターを出力し、その後に改行を出力することです。プロセス出力を囲む空白に興味がない場合は、次のようにstrip()を使用できます。

_>>> b'hi\n'.strip()
b'hi'
_
71
zigg

前述のように、_echo hi_は実際に_hi\n_を返しますが、これは予期される動作です。

ただし、おそらく「正しい」形式でデータを取得し、エンコードを処理したくない場合があります。あなたがする必要があるのは、_universal_newlines=True_オプションをsubprocess.Popen()に渡すだけです:

_>>> import subprocess
>>> print(subprocess.Popen("echo hi",
                           Shell=True,
                           stdout=subprocess.PIPE,
                           universal_newlines=True).communicate()[0])
hi
_

このようにPopen()はこれらの不要なシンボルを単独で置き換えます。

26
Danil

bはバイト表現で、\ nはエコー出力の結果です。

以下は結果データのみを印刷します

import subprocess
print(subprocess.Popen("echo hi", Shell=True,stdout=subprocess.PIPE).communicate()[0].decode('utf-8').strip())
7
Jenish