2017-02-10 8 views
0

このようなことについては、previous questionでは、成功の場合はコマンドの出力にアクセスし、エラーの場合は他のコードを実行する方法を学びました。しかし、通常は、エラーが発生した場合にコマンドの出力を出力する方が理にかなっています。他の質問を解決し、コードされました:エラーが発生した場合のシステムコマンドの出力方法

(with-output-to-string 
    (lambda() 
    (unless (system "ls -la") 
     ;; handle error here 
    ))) 

どのように私はunlessフォーム内のシステムコマンドの出力を得ることができますか?

使用例:いくつかのシステムコマンドを実行したいだけで、 "成功!"コマンドが成功した場合は端末に、エラーの場合は「エラー!コマンドの実際の出力に加えて

注:多くのシステムコマンドには副作用がありますので、私はこのコマンドを2回実行する必要はありません。私は2度トリガしたくないので、出力を得るだけです。このような2回目の呼び出しの出力は、とにかく最初の呼び出しは実際のエラーを反映しない可能性があります。

答えて

2

プロシージャprocessは、2つが入力ポート(サブプロセスのstdoutおよびstderrからパイプされたもの)である5つの値のリストを生成し、最後はサブプロセスの終了コードを取得するために使用できるプロシージャです。例えば、

> (process "someCommand") 
'(#<input-port:subprocess-stdout> 
    #<output-port:subprocess-stdin> 
    11292 
    #<input-port:subprocess-stderr> 
    #<procedure:control>) 

は、サブプロセスの終了コードを取得するには、引数 'exit-codeと(手順がある)最後の項目を呼び出す、といった:

((last (process "someCommand")) 'exit-code) 

をしかし、上記のことに注意してくださいプロシージャは、サブプロセスがまだ実行中の場合は整数の代わりに#fを返します。最初にそれを引数'waitで呼び出し、'exit-codeで呼び出します。例えば、

> (define cmd (process "someCommand")) 
> ((last cmd) 'wait) 
> ((last cmd) 'exit-code) ; should now return an integer 

終了コードについて比較することができ、それが非ゼロである場合には、stderr入力ポートを読み出して印刷することができます。以下

は、エラーが発生した場合のサンプルサブプロセスが正常に実行された場合"Success!"を生成する機能、及び印刷"Error! + error-message"ある:例えば

(define (output command) 
    (define cmd (process command)) 
    ((last cmd) 'wait) 
    (define exit-code ((last cmd) 'exit-code)) 
    (if (= exit-code 0) 
     "Success!" 
     (printf "Error!\n~a\n" (read-line (fourth cmd))))) 

> (output "date") 
Success! 
> (output "ls -al") 
Success! 
> (output "someCommand") 
Error! 
/bin/sh: 1: someCommand: not found 
+0

私が気付いたことは、 'read-line'を複数回呼び出すことができ、それはイテレータであるようです。私はすべての行を印刷します。私は '#'と比較するだけでよいでしょう。完全な出力を印刷するためのより良い方法はありますか? – Zelphir

+0

この回答で提供されているものを使用して作成しました。https://gist.github.com/ZelphirKaltstahl/2d229948cf0486854bd9e1a17589189a – Zelphir

+0

[read-string](https://docs.racket-lang.org/reference/Byte_and_String_Input。 html#%28def ._%28%28quote._〜23〜25カーネル%29._read-string%29%29)を使用して、入力ポートから複数の行を読み込むことができます。たとえば、 '(read-string 10000(fourth cmd))'は最大10000文字を読み込み、 'eof'に先行すると文字列を停止して返します。 10000を必要に応じて変更することができます。 – assefamaru

関連する問題