2017-11-01 8 views
1

私はRubyでコマンドを実行するためにopen3を使用するのに慣れています。実行中のシェルコマンドのクリスタル言語と出力のキャプチャ

def run_cmd(cmd, args) 
     stdout_str = IO::Memory.new 
     stderr_str = IO::Memory.new 
     result = [] of Int32 | String 
     status = Process.run(cmd, args: args, output: stdout_str, error: stderr_str) 
     if status.success? 
     result = [status.exit_code, "#{stdout_str}"] 
     else 
     result = [status.exit_code, "#{stderr_str}"] 
     end 
     stdout_str.close 
     stderr_str.close 
     result 
    end 

    cmd = "ping" 
    hostname = "my_host" 
    args = ["-c 2", "#{hostname}"] 
    result = run_cmd(cmd, args) 
    puts "ping: #{hostname}: Name or service not known" if result[0] != 0 

がこれを行うには良い方法があります:クリスタル-LANGで同等のlibがあるようには思えないので、私はこれを適当に組みあわせ?クリスタルランを探索しているソフトウェア開発者ではない退職したネットワークスペシャリストによると、

すべてのアドバイスを事前におねがいします。

答えて

6

おそらくこの:

def run_cmd(cmd, args) 
    stdout = IO::Memory.new 
    stderr = IO::Memory.new 
    status = Process.run(cmd, args: args, output: stdout, error: stderr) 
    if status.success? 
    {status.exit_code, stdout.to_s} 
    else 
    {status.exit_code, stderr.to_s} 
    end 
end 

我々は、それがどのOSリソース、メモリのちょうどブロックへのハンドルを表していないので、IO::Memoryを閉じる必要はありませんし、我々は配列の代わりにタプルを使用リターン。これは、発信者が2つのアイテムを正確に返すことを知っていることを意味し、最初の数字は数字で、2番目の数字は文字列です。配列を返すと、呼び出し元はint32か文字列のいずれかである可能性のある項目をいくつでも返すことしか知りません。

あなたは、このようにそれを使用することができます:

cmd = "ping" 
hostname = "my_host" 
args = ["-c 2", hostname] 
status, output = run_cmd(cmd, args) 
puts "ping: #{hostname}: Name or service not known" unless status == 0 
+0

スウィートを!どうもありがとうございました。 – lewis

関連する問題