2016-04-05 27 views
6

端末から出力されたifconfigコマンドからIPを取得する単純なスクリプト実行サブプロセスです。 subprocess.check_output()は常に\nという値を返します。Pythonのサブプロセス出力なし n

を除き、戻り値を返すことを希望します。 これはどのように行うことができますか?一般的な方法については

$ python 
>>> import subprocess 
>>> subprocess.check_output("ifconfig en0 | awk '{ print $2}' | grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}'", shell=True) 
'129.194.246.245\n' 
+2

'echo'その改行.. –

+0

なしていないだけを追加します。もし、 'subprocess.check_output(" ifconfig en0 | awk '{print $ 2}' | grep -E -o '([0-9] {1,3} [\。]){3} [0-9] {1,3} '"、shell = True)' bash mac OS Xで私のIPアドレスを取得すると、返信行も表示されます – Jupiter

+0

echo -nはエコー改行を持ちません。または、サブプロセス行の末尾に.strip()を追加してください。 – Benjamin

答えて

15

subprocess.check_output("echo hello world", shell=True).strip() 
+0

これは答えられません*なぜ*出力に改行がありますか? 'echo'または' grep'出力のいずれかになります。ヒント:それを追加するのは 'check_output()'ではありません。 –

+4

質問はなぜではなく、それを削除する方法ではありません:-D答えは、コマンドラインバイナリは出力の最後に新しい行を追加して、(別の行で)素敵なシェルプロンプトを表示するということです。 – Benjamin

+0

私は、質問の解釈がちょっと違うと思います。 * 'subprocess.check_output()'は常に '\ n' *で値を返します。そして、OPは、 'grep -o'でさえも(改行のソースとしてエコーを指し示す答えが間違っていることを証明するように)それらの改行をまだ得ていることを示すために質問を変更しました。 –

1

subprocess.check_output()は、改行を追加しません。 echoです。 (そう/bin/echoを使用)内蔵の実施シェルを使用してを回避するには、改行を抑制するために-nスイッチを使用することができますが、に持っている:あなたの代わりにecho -nを使用する場合は、文字列を得ることができる

>>> import subprocess 
>>> subprocess.check_output('/bin/echo -n hello world', shell=True) 
'hello world' 

'-n hello world\n'すべてのsh実装が-nスイッチサポートecho(OS Xなど)をサポートしているとは限らないためです。

あなたは常にもちろん、空白を削除するstr.rstrip()またはstr.strip()を使用することができますが、ここでsubprocessを非難しないでください:

>>> subprocess.check_output('echo hello world', shell=True).rstrip('\n') 
'hello world' 

ご質問更新がawkgrepを使用して、より複雑な例を追加しました:

subprocess.check_output("ifconfig en0 | awk '{ print $2}' | grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}'", shell=True) 

ここでgrepは(最終)改行を追加します。 grep -oの一致するテキストを印刷することができますが、引き続き別のマッチに改行を追加します。

-o
--onlyマッチング

プリントマッチラインのみ一致した(空でない)部品、別々の出力ライン上のそのような各部分とgrep manualを参照。

強調鉱山。あなたは、パイプの出力から任意の改行を削除するために最後にtr -d '\n'を追加することができます

>>> subprocess.check_output(
...  "ifconfig en0 | awk '{ print $2}' | " 
...  "grep -E -o '([0-9]{1,3}[\.]){3}[0-9]{1,3}' | " 
...  "tr -d '\n'", shell=True) 
'172.17.174.160' 
+0

これは必ずしもエコーについての質問ではないと思います。「rstrip」はOPに必要なものです。 –

+1

@PadraicCunningham:それは*依存しています。そして、 'check_process'がこの改行を加えるという前提が正しくないことを指摘することは重要です。 –

+1

@PadraicCunningham:質問に変更があった場合、OPは改行が 'check_output 'によって追加されたと主張しています。 'str.rstrip()'で改行を削除できることはここでは重要ではありません。 –

0

あなたが任意の改行をstr.rstripかマルタインが示唆ものを使用することができ、あなたもでのpythonを使用して出力を解析することができます任意の改行を追加しませんawkのまたはgrepのする必要があります。

あなたは分割することができます:

out = subprocess.check_output(["ifconfig", "en0"]) 

for line in out.splitlines(): 
    if line.lstrip().startswith("inet "): 
     print(line.split()[1].split(":", 2)[1]) 
     print(ip.search(line)) 
     break 

したり、独自の正規表現を使用します。あなたはAWKやgrepを必要としないという

import re 

out = subprocess.check_output(["ifconfig", "en0"]) 

print(re.search('([0-9]{1,3}[\.]){3}[0-9]{1,3}', out).group()) 

ポイントを。

ipv4またはipv6にマッチさせ、エラーが返されたときにキャッチする場合は、CalledProcessErrorをキャッチして、0以外の終了ステータスにすることができます。ipv4では正規表現を使用するのは簡単ですがipv6では、inet6を使用してipv6アドレスを取得する方が簡単です。

from subprocess import check_output, CalledProcessError 
import re 

def get_ip(iface, ipv="ipv4"): 
    try: 
     out = check_output(["ifconfig", iface]) 
    except CalledProcessError as e: 
     print(e.message) 
     return False 
    try: 
     if ipv == "ipv4": 
      return re.search('([0-9]{1,3}[\.]){3}[0-9]{1,3}', out).group() 
     return re.search("(?<=inet6 addr:)(.*?)(?=/)", out).group().lstrip() 
    except AttributeError as e: 
     print("No {} address for interface {}".format(ipv, iface)) 
     return False 

デモ:

In [2]: get_ip("wlan0") 
Out[2]: '192.168.43.168' 

In [3]: get_ip("wlan0","ipv6") 
Out[3]: 'fe80::120b:a9ff:fe03:bb10' 

In [4]: get_ip("wlan1","ipv6") 
wlan1: error fetching interface information: Device not found 
Out[4]: False 
+0

'str.lstrip( 'addr:')'?これは文字 'a'、' d'、 'r'、': 'を最初から削除します。任意の順序で。 IPv6アドレスがある場合はどうなりますか? –

+0

@MartijnPieters。 Am、あなたはinet6を探します。また、 ':'に分割することもできます。多くのオプションがあります。 –

+3

プレフィックスを削除するのに 'lstrip'を使うべきではありません。 –