2016-08-20 2 views
3

ログにgrep検索を実行して結果を出力するスクリプトを作成しようとしています。 サブプロセスよりも簡単なのでEnvoyを使用しようとしますが、grepコマンドを実行すると、そのようなファイルoディレクトリがないというエラーが返されます。grep envoy.runでそのようなファイルやディレクトリがありません

ディレクトリ構造が簡単である:

  • 。スクリプトの#ルート
  • #スクリプトファイル

マイtest.pyで検索するログイン含まれてい

  • web_logs /ログ/#DIRが簡単です
  • test.py:出力

    import envoy 
    
    def test(value): 
    
        search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*" 
        print(search) #check of the search string 
        r = envoy.run(search) 
        print(r.status_code, r.std_out, r.std_err)#check of the command 
        response = r.std_out 
    
    if __name__ == "__main__": 
        test(2) 
    

    次のとおりです。

    grep 'cv=2' ./web_logs/log/log_* 
    (2, '', 'grep: ./web_logs/log/log_*: No such file or directory\n') 
    

    私は同じコマンドを実行した場合

    grep 'cv=2' ./web_logs/log/log_* 
    

    ログファイルに文字列 "cv = 2"が含まれています。

    どこがエラーですか?

    更新答え 後の問題は、それがあると私は特使を改善するためにグロブモジュールの使用して、より良い勉強しようとして、私は、サブプロセスを使用して特使はグロブモジュールを使用せずに爆発することができないこと*の使用です。

    私が使用した新しいコードは次のとおりです。

    import subprocess 
    
    def test(value): 
    
        search = "grep 'cv="+str(value)+"' ./web_logs/log/log_*" 
        print(search) #check of the search string 
        proc = subprocess.check_output(search, shell=True) 
        print proc.split('\n') 
    
    if __name__ == "__main__": 
        test(2) 
    
  • +0

    'c = 2'を等号が含まれていない項に変更するとうまくいきますか?私は「特使」には慣れていないので、これは間違いなく暗闇の中のショットです。 – tripleee

    答えて

    1

    @baptistemmは、右のグロブが機能していない、あなたのプロセスの一環として、あなたが実行していないので、bashで実際にあるPython用glob moduleがあります。

    しかし、何が起こっているのか少し深いです。

    サブプロセスを実行すると、いくつかのシステムサービス(システムコール)の1つでサブプロセスを実行できます。

    import envoy 
    
    def test(value): 
    
        search = "/bin/sh -c \"grep 'cv="+str(value)+"' ./web_logs/log/log_*\"" 
        print(search) #check of the search string 
        r = envoy.run(search) 
        print(r.status_code, r.std_out, r.std_err)#check of the command 
        response = r.std_out 
    
    if __name__ == "__main__": 
        test(2) 
    

    グロブの世話をするシェルコマンドとしてコマンドを実行:;

    短い答え(TLDR)

    はここでこれを行うには正しい方法です。

    長い答え

    サブプロセスが実行されるたびに、それは最終的にはexecveシステムコール(または同等)に変換されます。

    Cライブラリには、system(3)popen(3)などのヘルパー機能があり、簡単な方法で実行する方法を提供するためにexecve(2)を囲んでいます。 systemはシェルを起動し、その引数をそのままシェルの-cオプションに渡します。 popenは余分な魔法をします。

    エンベイでは、エンボイコードの|def expand_args(command):参照)の引数が解析されます。プロセスを実行するためにpopenの等価物を使用します。 envoyは本質的にシェルが|マーカーで行うことです(|を介して物を分割してからpopenを使用します)。

    エンベロープが行っているのは、*をシェルとして解釈することです。何らかの種類の関数globを使用してファイルを一致させるように展開します。バッシュはそうです。従って私の答え。

    特典にコードを提供して、それをグロブにすることが楽しい演習です。

    +0

    baptistemmと@Ahmedの両方に感謝します。私はAhmedをもう一つの中心として選択しました。私のコードに問題があります。私はすぐにサブプロセスの使用について私の答えを更新します。特使を改造しようとする(たとえ最後の更新が長い時間前に行われたとしても...) – Smilzao

    1

    それは、端末で動作しますが、特使に(bash example)をグロブに関連していないのはなぜ。あなたのターミナルで実行する場合

    grep 'cv=2' ./web_logs/log/log_* 
    

    bashは、コマンドラインを解析し、一致するファイルのすべての出現とスターの文字に置き換えられます。あなたは./web_logs/log/log_1./web_logs/log/log_2./web_logs/log/log_fooを持っている場合は、特使で同じことを実行して、異なるだろうと、それはそれはに渡すよファイルのglobingを実行しませんときに、あなたのコマンドは、実際に

    grep 'cv=2' ./web_logs/log/log_1 ./web_logs/log/log_2 ./web_logs/log/log_foo 
    

    になりますgrep存在しない./web_logs/log/log_*という名前のファイルは、あなたの質問に貼り付けた行で実際に確認されています。

    print r.std_err 
    'grep: ./web_logs/log/log_*: No such file or directory\n' 
    

    PSは:

    +0

    彼のスクリプトを修正すると良いでしょう。 –

    +0

    重要な点は、彼のエラーは実際にenvoy.runがサブプロセスを実行する方法を誤って解釈したことであり、グロブの問題として現れているという事実は単なる副作用です。 –

    +0

    私が原因を知っている間、私は使者を知らないので、解決策はありませんでした。 – baptistemm

    関連する問題