私はこれが古いスレッドだと知っていますが、軽く触れられた別のオプションがあります。SimonHürlimann
このトピックに関する多くの情報はありません。これは、必要がある他の人に役立つと思います。
この例では、我々はあなたの同期または非同期のコマンドを実行することができますし、標準出力を提供し、stderrの、終了コード、およびPIDたOpen3
を使用します。
Open3は、別のプログラムを実行しているときに、子プロセスを待つためにstdout、stderr、終了コードとスレッドにアクセスします。 Process.spawnと同じ方法で、プログラムのさまざまな属性、リダイレクト、現在のディレクトリなどを指定できます。 (ソース:Open3 Docs)
出力をCommandStatus
オブジェクトとしてフォーマットすることを選択しました。これには、stdout
,stderr
,pid
(ワーカースレッドの)とexitstatus
が含まれています。 STDOUT/ERRバッファを読んでいる間
class Command
require 'open3'
class CommandStatus
@stdout = nil
@stderr = nil
@pid = nil
@exitstatus = nil
def initialize(stdout, stderr, process)
@stdout = stdout
@stderr = stderr
@pid = process.pid
@exitstatus = process.exitstatus
end
def stdout
@stdout
end
def stderr
@stderr
end
def exit_status
@exitstatus
end
def pid
@pid
end
end
def self.execute(command)
command_stdout = nil
command_stderr = nil
process = Open3.popen3(ENV, command + ';') do |stdin, stdout, stderr, thread|
stdin.close
stdout_buffer = stdout.read
stderr_buffer = stderr.read
command_stdout = stdout_buffer if stdout_buffer.length > 0
command_stderr = stderr_buffer if stderr_buffer.length > 0
thread.value # Wait for Process::Status object to be returned
end
return CommandStatus.new(command_stdout, command_stderr, process)
end
end
cmd = Command::execute("echo {1..10}")
puts "STDOUT: #{cmd.stdout}"
puts "STDERR: #{cmd.stderr}"
puts "EXIT: #{cmd.exit_status}"
、私はcommand_stdout
変数が割り当てられているかどうかを制御するcommand_stdout = stdout_buffer if stdout_buffer.length > 0
を使用しています。データが存在しない場合は""
の代わりにnil
を渡す必要があります。後でデータを渡すときはより明確です。
あなたはおそらく私にcommand + ';'
を使用していることに気づいたでしょう。最初の形式から文字列(のexec(「コマンド」))これら の単純なルールに従うならば
:この理由は、(popen3が使用するものである)Kernel.execからの文書に基づいています
- なしメタ文字
- 何のシェル予約語はなく、特別なビルトイン
- Rubyはシェル
せずに直接コマンドを起動します210
シェルの呼び出しを強制するには、 ";"文字列に、単にあなたが不正なコマンドを渡すと'spawn': No such file or directory
エラーを投げてからルビーを防ぐこの
( ので、「」メタ文字があります)。代わりに、エラーを正常に解決し、キャッチされない例外ではなくSTDERRとして表示されるカーネルに直接渡します。
だから、このクラスを公開して、エンドユーザに完全にフィルタリングされない(私はしません)と、シャドーハッシュを提供してからユーザ名として "username; rm -rf /"を指定したとしましょう'/' – arbales
を取り消す効果があります。引数は実行されたプログラムに直接渡されます。これはあなた自身で確認できます。 'ruby -e 'system * W(ls -l foo; rm -rf /)'' – cam
ああ、うまく動くようにしてみてください。それは完璧な意味合いをします。私は、アプリケーションが安全であることを保証することは、すべてのために危険なエッジケースが存在するかのように、単純なステップや事実よりも困難である必要があります。これは、私がそれについて大いに読んだり、学んだことがないためです。 – arbales