質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.39%
LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

12023閲覧

Pythonから別プログラムを実行し、その出力を実行元で得たい。

TanakashiXr

総合スコア57

LINE Messaging API

LINE Messaging APIは、メッセージの送信・返信ができるAPIです。Web APIを経由しアプリケーションサーバとLINEのAPIでやり取りが可能。複数のメッセージタイプや分かりやすいAPIリファレンスを持ち、グループチャットにも対応しています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/11/14 11:40

編集2018/11/15 13:59

前提・実現したいこと

Pythonから別プログラムを実行し、その出力を実行元で得たい。
下記のようにプログラムを書いたのですが何も出力されず実行されたところで止まってしまいます。

該当のソースコード

Python3

1elif text.lower() == 'restart': 2 cl.sendMessage(to, "再起動中...") 3 cl.sendMessage(to, "再起動しました。再ログインしてください。") 4 #restartBot() 5 path = "restart.txt" 6 p = subprocess.Popen (('python x.py'), stdout = subprocess.PIPE, shell=True) 7for l in p.stdout: 8 print = l.strip () 9 #cl.sendMessage(to, str(print)) 10 with open(path, mode='w') as f: 11 f.write(str(l)) 12 with open(path) as f: 13 cl.sendMessage(to, f.read()) 14ret = p.wait () 15cl.sendMessage(to, '正常に再起動しました'.format (ret))

調べたものの、分からなかったためお分かりの方いらっしゃれば
ご教授お願い致します。

追記

OS: # cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) Python: # python --version Python 3.5.0

実行はLINEから「restart」と言うメッセージを得たら、実行される仕組みになってます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

以下にてリアルタイムにサブ側の標準出力を取得することができます。
注意点としては、サブ側でのprint関数での出力だとバッファに溜まりリアルタイムで取得できないようです。
その代わりに直接stdout.write(+バッファをフラッシュする必要があります。
参考:Pythonのsubprocessで標準出力をリアルタイムに取得する

メイン側(main.py)

Python

1import subprocess 2import datetime 3 4p = subprocess.Popen(('python x.py'), stdout = subprocess.PIPE, shell=True) 5with open('restart.txt','w',encoding='utf-8') as f: 6 while True: 7 # サブ側の標準出力をうける 8 line = p.stdout.readline() 9 if line is not None: 10 line = line.decode().strip() 11 if len(line) > 0: # 最後にバッファから空文字が大量に吐き出される?対策 12 f.write(line+'\n') 13 print(line,datetime.datetime.now()) # リアルタイムか確認用に日時も出力 14 # cl.sendMessage(to, line) 15 16 # サブ側が終了 17 if p.poll() is not None: 18 ret = p.returncode 19 break 20print('正常に再起動しました[{}]'.format(ret)) 21#cl.sendMessage(to, '正常に再起動しました'.format (ret)) 22 23""" 24x:0 2018-11-15 08:04:11.699754 25x:1 2018-11-15 08:04:12.700563 26x:2 2018-11-15 08:04:13.701458 27x:3 2018-11-15 08:04:14.701805 28x:4 2018-11-15 08:04:15.701997 29正常に再起動しました[0] 30"""

サブ側(x.py)

Python

1import time 2import sys 3 4for i in range(5): 5 #print('x:',i) 6 # 直接標準出力に吐き出しバッファをクリアする! 7 sys.stdout.write('x:{}\n'.format(i)) 8 sys.stdout.flush() 9 time.sleep(1)

検証環境

Win10+Anaconda(Python3.5.x)+コマンドプロンプト上に加え
以下のWSL(Windows Subsystem for Linux)のLinux環境でも正常動作することを確認。
OS:Ubuntu 14.04.5 LTS
Python:3.4.3
実行手段:ターミナル(bash)上からpython3 main.pyにて実行。

投稿2018/11/14 23:10

編集2018/11/15 15:12
can110

総合スコア38337

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TanakashiXr

2018/11/15 04:59

ご丁寧にありがとうございます! 出力が得られません。。。なぜなのでしょうか? ちなみにメイン側とサブ側は同じプログラムです。
can110

2018/11/15 05:18

まずは回答コードの動作の結果について教えてください。正常に動作しますか?
TanakashiXr

2018/11/15 05:19

エラーも何も出力されませんでした。 動作はしているのかと。。。
can110

2018/11/15 05:24 編集

OS、Pythonバージョンなど環境、プログラムの実行手順(ターミナル、コマンドプロンプトから~)などの詳細を教えてください。 当方Windows10+Python3.5にてコマンドプロンプト上からメイン側プログラムを実行しています。
can110

2018/11/15 15:01

もう一度確認なのですが 回答に示したメイン側コードを、Linuxでのターミナル上で実行した場合(サブ側は単純に1秒毎に出力するもの)、エラーも何も出力されなかったのでしょうか?
TanakashiXr

2018/11/15 15:21

はい、されませんでした。 どこか違うとこに出力されているのでしょうか?
can110

2018/11/15 15:28

回答に追記しましたが、Win10に加えUbuntu上でも動作確認できました。 回答コードは最も単純な例なので、これで動作しないとなると、ちょっと手に負えない感じですね。
guest

0

自己解決

テキストファイルに直接記載し、それを読み込む方法をとりました

投稿2018/12/22 07:16

TanakashiXr

総合スコア57

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

サブプロセスの出力をメインで再出力することをしてみました。

python

1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3#main 4import sys 5import os 6import subprocess 7 8p = subprocess.Popen (('python3 ~/python_folder/test/hello.py'), stdout=subprocess.PIPE, shell=True) 9 10p.wait() 11stdout_data, stderr_data = p.communicate() 12out = str(stdout_data) 13out = out[2:-3] 14 15print(out + " main") 16

python

1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3#hello.py 4print("hello world") 5

出力結果
hello world main

短い文字出力ではp.stdout.read()でもできましたが、長い文字出力の場合は、p.communicate()を使用するようです。
100KBくらいまではいけるようです。
質問者のデータ出力量がどのくらいかわからないため、回答になっているかわかりませんが参考になれば幸いです。

参考リンク
https://qiita.com/mokemokechicken/items/a84b0aa96b94d1931f08

投稿2018/11/14 13:12

GOTA77

総合スコア160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

TanakashiXr

2018/11/14 18:54

サブプロセスの終了を待たずにリアルタイムで出力するにはどうすればいいのでしょうか?
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.39%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問