30

小さなファイル構造が進行中のプログラムを持っており、それを使用して実行されます

python do_work.py foo bar

Railsユーザーにボタンを押してもらいたいのですが、結果がどこかにアップロードされるか、ダウンロードリンクまたはそのようなものとしてスローされます- do_work.py(たとえば、それはresult.txt)の出力です

また、スクリプトの結果、テキスト ファイルではない 3 つの個別のファイルがファイル システム上に作成されることも明確にしたいと思います (これは重要ではなく、ここでは実際の問題ではありません)。

それについて行く最善の方法は何ですか?rake で exec Python を実行できますか? さらに重要なことは、これはherokuで実行可能ですか?

システムに Python がインストールされていますが、sockmonk から提供された回答が機能していないようです - nil が返されます。気をつけてください、他のコマンドのようなlsものはうまくいくようです。

パーミッションの問題でしょうか?

def index
    value = %x( python --version )
    render :text => value
end

ちなみに、これを試してみてirbください:

%x(python)

irb の内部にある Python ターミナルを起動します。ただし、何らかの理由でパラメーターは必要ありません。

4

5 に答える 5

27

そのバージョンを STDOUT ではなく STDERR に出力するindexため、メソッドは機能しません。python --versionこれらのストリームを分離する必要がない場合は、STDERR を STDOUT にリダイレクトするだけです。

value = %x(python --version 2>&1)

この呼び出しは同期的であるため、スクリプト ( python do_work.py foo bar 2>&1) を実行すると、生成されたファイルを読み取ることができるはずです。

何らかの理由でスクリプトがファイルを作成できない場合、valueエラー メッセージは通常 STDERR に送信されるため、変数に例外が表示されます。

STDERR を STDOUT から分離したい場合は、Open3モジュールを使用してください。

スクリプトの実行には時間がかかるため、呼び出しが重複する可能性があることに注意してください。これを防ぐために、ここでキューを使用します。

また、ユーザーが入力したデータを確認することを忘れないでください。スクリプトに直接渡さないでください。

于 2013-05-05T04:33:59.150 に答える
4

一部、データの形式に依存します。長すぎず、ブラウザーで直接レンダリングできる場合は、Rails コントローラーで次のようにすることができます。

result = `python do_work.py foo bar`
render :text => result

結果がプレーン ASCII テキストであると仮定すると、結果はブラウザに直接送信されます。do_work.py へのパラメーターがユーザーからのものである場合、最初にそれらを検証する必要があります。その場合、おそらく system() 呼び出しを使用する方が安全です。

結果をファイルとして送り返したい場合は、ファイルを作成するための ruby​​ の Tempfile クラス (永久に固執しない方法で) と、結果を送り返すためのいくつかの異なるオプションについては、Rails の send_file および send_data コマンドを参照してください。その方法。

于 2013-04-30T18:01:36.437 に答える
1

Python スクリプトをどの程度深く統合するかによって異なります。実際に Ruby から直接 Python モジュールを呼び出す方法があります。

http://www.goto.info.waseda.ac.jp/~fukusima/ruby/python-e.html

これにより、I/O デバイスを経由する代わりに、Python スクリプトから直接出力を取得できるという利点が得られます。

于 2013-05-10T00:44:32.930 に答える
1

私は次のようなことをします。

このタスクをバックグラウンドで非同期に実行します。結果の準備ができたら、それをユーザーに報告します。

これを実現する方法の 1 つは、Open3delayed_job gem を使用することです。

Open3 モジュールのpopen3メソッドを見てください。

Open3.popen3([env,] cmd... [, opts]) {|stdin, stdout, stderr, wait_thr|
  pid = wait_thr.pid # pid of the started process.
  ...
  exit_status = wait_thr.value # Process::Status object returned.
}

あなたの場合、Open3.popen3ステートメントを次のようなものに変更できます

Open3.popen3("python do_work.py foo bar"){
  ...
  # mechanism for reporting like setting a flag in database system
  # or queue system
}

注: Python スクリプトへのフル パスを指定する必要があります。

そして、delayed_job gem を使用して、これをバックグラウンド タスクとして実行します。

また、システムをポーリングしてフラグが設定されているかどうかを確認するポーリングメカニズムも必要です。これは、結果の準備ができていることを意味し、ユーザーに提供することを意味します。

于 2013-05-10T02:16:04.130 に答える