2017-04-12 5 views
1

私は中に大量のシェルコマンドを実行する中程度の大きさのpythonスクリプトを持っています。これらのコマンドをすべて実行してから、pythonスクリプトの制御フローをトレースすることができます。実行前にpythonスクリプトから起動されたすべてのシェルコマンドをコンソールに出力する

このスクリプトでは、osモジュールのsystem()、サブプロセスモジュールのcall()、popen()、check_output()などのシェルコマンドを実際に実行するために複数のコマンドを使用します。これを行う最も簡単な方法は何でしょうか?

私は、実行前にシェルコマンドの引数を表示するラッパー関数を考えていましたが、正しい呼び出し/ Popenまたはその他のコマンドをユーザーの裁量に従って呼び出すことができる一般的な関数を記述する方法はわかりません。また、これらの呼び出しには異なる数と種類の引数が含まれていることに注意する必要があります。

ありがとうございます!

答えて

1

傍受したいさまざまな呼び出しに対して、decoratorをビルドしてインストールします。でも「組み込み」関数はファーストクラスのオブジェクトであるため、ロギングのバージョンに置き換えることができます。

import os 

def log_wrap(f): 
    def logging_wrapper(*args, **kwargs): 
     print("Calling {} with args: {!r}, kwargs: {!r}".format(f.__name__, args, kwargs)) 
     return f(*args, **kwargs) 

    return logging_wrapper 

os.system("echo 'Hello, world!'") 
os.system = log_wrap(os.system) 
os.system("echo 'How do you like me now?!'") 

このコードを実行(のpython3)プリントは:

$ python test.py 
Hello, world! 
Calling system with args: ("echo 'How do you like me now?!'",), kwargs: {} 
How do you like me now?! 

注意最初の間の2番目の呼び出しはos.systemに、私はos.system関数を引数を元の関数に渡す前にログメッセージを出力する関数に置き換えました。あなたは...

+0

感謝をファイルにログメッセージを印刷し、または(より良いまだ)loggingモジュールを呼び出す、またはpdbデバッガ、または何でもあなたが好きを呼び出すことができます!正確に私が探していたもの(Y) –

0

あなたは子プロセスを開始しますが、あなたの行動を記録したいので、あなたが標準エラー出力、子プロセスの標準出力を記録する必要があります、

import subprocess as sp 
import datetime 
dt=datetime.datetime.now().strftime("%Y%m%d%H%M00") 
ofd = open("res.sql","w+") 
efd = open("log/cmd-{}.log".format(dt),"a+") 

は、あなたが(たとえば、mysqldumpを)コマンドを構築しているとあなたが持っていると仮定データベース、テーブル、資格情報のファイル名(db、tbl、cnf)が読み込まれます。あなたは、EFD、OFD閉じることを忘れないでください

proc = sp.Popen(args, shell=False, stdin=sp.PIPE, stdout=ofd, stderr=efd) 
stdout,stderr = proc.communicate 
rc = proc.wait() 
if rc>0: print "error",rc,"dbdump failed" 
else: print "result",stdout,stderr 
、あなたが実行しようとしているコマンドを印刷

args = ["mysqldump","--defaults-extra-file="+cnf,"--single-transaction","--quick",db,tbl] 
print " ".join(args) 

、あなたは(OFD、EFD)を超える出力とエラーファイルを開いていると仮定し、

たい。

0
import commands 

commands = r'''find .''' 
result = commands.getstatusoutput(command)[0] 
print("Command: {}\nresult: {}".format(command,result)) 
+0

質問に対する答えはほとんどありません。 OPは 'print'を使う方法をよく知っていますが、問題はどこにでも' print'sを挿入する大きなコードベースを編集しないでください。 – phd

+1

@phdはい、ただし、削除を保証するものはありません。あなたは答えの正確さを判断するのではなく、サイトに適しているかどうかを判断しています。私はあなたがそれを間違ってやっていることを見てみることをお勧めします:低品質投稿キューの正気のための嘆願](https://meta.stackoverflow.com/questions/287563/youre-doing-it-wrong-a-低品質のポスト待ち行列)を使用することができます。 – Zizouz212

関連する問題