2011-11-16 4 views
1

ココア初心者警告!シェルコマンドから出力をキャプチャするにはどうすればよいですか?

Iは、プロセスが実行されているかどうかを判断する良い方法であると、次のシェル・コマンドを見つける(1 =実行中、0 =動作していない):

if [ $(ps -Ac | egrep -o 'ProcessName') ]; then echo 1; else echo 0; fi; 

I「はシステムとココアにこれを組み込むことができ「コマンド:

system("if [ $(ps -Ac | egrep -o 'Finder') ]; then echo 1; else echo 0; fi;"); 

しかし、出力が実行ログを対象としている、と私は私のココアコードに(1または0)の結果をキャプチャする方法を見つけ出すことはできません。

私は次のようにNSTaskでこれを実装してみました:

NSTask *task = [[NSTask alloc] init]; 
[task setLaunchPath:@"/bin/sh"]; 
[task setArguments:[NSArray arrayWithObject:@"if [ $(ps -Ac | egrep -o 'Finder') ]; then echo 1; else echo 0; fi;"]]; 
NSPipe *pipe = [NSPipe pipe]; 
[task setStandardOutput:pipe]; 
[task launch]; 
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile]; 
[task waitUntilExit]; 
[task release]; 
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
NSLog (@"%@", output); 
[output release]; 

しかし、これは、次のエラーメッセージを生成:[$場合

を(PS -Ac | egrepの-o 'ファインダー') ];次にエコー1。 else echo 0;このファイルまたはディレクトリはありません

出力(1または0)をコードでキャプチャできるようにこのシェルコマンドを正しく実装する方法を教えてください。 (私はプロセスが実行されているかどうかを判断する他の方法を知っていますが、私の質問の理由の一部は、ココア内のシェルスクリプトを一般的に実装する方法を学ぶことです)。

ありがとう問題。

+2

これはどのように動作するのかを見るには、なぜスターターにとって比較的複雑な表現に頼るのですか? 'echo 1'が動作するかどうか確認してください。また 'No such file or directory' msgのために、system()が直接ローカルディレクトリを呼び出し、ファイル名が' if ... 'であることを確認します。シェルのパスと '-e'(オプションを実行する?)を入れて、単純なケーステスト' [task setArguments:[NSArray arrayWithObject:@ "/]を生成する必要があると思いますbin/bash -e 'echo 1' "]]'を実行します。なぜあなたのファイルシステムに保存されたスクリプトを呼び出すためにあなたのコードを使用するだけではありませんか?がんばろう。 – shellter

+1

シェルスクリプトはシェルによって実行されます。 'system()'からシェルを実行するには、 'system(" sh -c 'echo moo' ")'のようなものを使用します。コマンドの出力ではなく、 'system()'から結果コードを取得するほうが良いですし、 'if'と' echo'sは必要ありません: 'system(" sh -c 'ps -Ac | egrep -o Finder '")'と一致するかどうかを示す 'egrep'の終了コードが返されます。 – tripleee

+1

psの出力をテストする必要はありません。 egrep。代わりにegrepの戻り値をテストします。 IOW、 "ps -Ac | egrep -o 'Finder'>/dev/null"と書いてください(または単にpgrepを使ってください)。 –

答えて

1

ロブを見て、それをしない方法を見ることができ、可能な限りコードでダイレクトソリューションの使用に関する一般的な指針をありがとうございました。私は、朴総裁のsysctlのラッパーと、Appleのpsソースコードを調べました。組み込むのにはしばらく時間がかかりますが、プロセスのリストを取得するための直接的な解決策をどこから探すべきかはわかっています。

shellterとtripleeeについては、シェルコマンドとのやりとりに関するご意見をありがとうございます。あなたの提案に基づいて、私は働く3つの方法を得ました(!):

BOOL processIsRunning = system("ps -Ac | grep 'ProcessName' > /dev/null") == 0; 

方法2は、シェル-cオプションでNSTaskを使用しています(-cではなく-eに注意してください):

NSTask *task = [[NSTask alloc] init]; 
[task setLaunchPath:@"/bin/sh"]; 
[task setArguments:[NSArray arrayWithObjects:@"-c",@"ps -Ac | grep 'ProcessName'",nil]]; 
NSPipe *pipe = [NSPipe pipe]; 
[task setStandardOutput:pipe]; 
[task launch]; 
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile]; 
[task waitUntilExit]; 
[task release]; 
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
BOOL processIsRunning = [result length] > 0; 

方法1 systemコマンドのリターンコード(egrep -oは必要ありません)を使用しています

方法3もシェル-cオプションでNSTaskを使用しますが、この場合、実行するコマンドは独自のを持つ別のシェルです10オプション(これは実行するコマンドにif構成を組み込むために多くの試行錯誤の後で見つけることができた唯一の方法でした。もちろん、それは、方法現在の問題のためやり過ぎ)です:

NSTask *task = [[NSTask alloc] init]; 
[task setLaunchPath:@"/bin/sh"]; 
[task setArguments:[NSArray arrayWithObjects:@"-c",@"/bin/sh -c 'if [ \"$(ps -Ac | egrep -o 'ProcessName')\" = \"ProcessName\" ]; then echo 1; else echo 0; fi;'",nil]]; 
NSPipe *pipe = [NSPipe pipe]; 
[task setStandardOutput:pipe]; 
[task launch]; 
NSData *data = [[pipe fileHandleForReading] readDataToEndOfFile]; 
[task waitUntilExit]; 
[task release]; 
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 
BOOL processIsRunning = [result intValue] == 1; 

は素晴らしい助けありがとうございました。ここで

3

あなたは間違っています。 「外部プロセスを実行してXを実行するにはどうすればよいですか」と尋ねるのではなく、「Xを実行するコードを作成するにはどうすればよいか」と尋ねるべきです。

外部スクリプトを使用してプロセスのリストを取得する必要はありません。一般に、パフォーマンスとセキュリティの両方の理由から、外部タスクを起動するのではなく、常にAPIを使用するようにしてください。

この場合、必要なAPIはsysctl Cインターフェイスです。

JongAm Parkは、実行プロセスのリストを取得するためにsysctlを使用するためにObjective-C wrapperを書いています。彼のポストのコメントにも良い点があります。

また、あなたはAppleがthe source code for the ps command.

0

は全くココアを含まない一般的な答えです:

あなたはsystem()からの出力を取得したい場合は、system()を使用していない、popen()を使用しています。

+0

ありがとうございます。私はpopen()を調べます。問題を解決するための多くの方法! – scolfax

関連する問題