2011-01-07 15 views
0

コマンドを実行するためにNSTaskで何かが見つかりましたが、動作させることができません。私のココアアプリでこのコマンドを実行するには?

これは私のコマンドです:

ioreg -c BNBMouseDevice | grep BatteryPercent 

私はココアのアプリでこれを実行するにはどうすればよいですか? (もちろんプログラムで)

ありがとうございました。

NSTask *server = [NSTask new]; 
[server setLaunchPath:@"/bin/sh"]; 
[server setArguments:[NSArray arrayWithObject:@"ioreg -c BNBMouseDevice | grep BatteryPercent"]]; 
NSPipe *outputPipe = [NSPipe pipe]; 
[server setStandardInput:[NSPipe pipe]]; 
[server setStandardOutput:outputPipe]; 
[server launch]; 
[server waitUntilExit]; 
[server release]; 
NSData *outputData = [[outputPipe fileHandleForReading] readDataToEndOfFile]; 
NSString *outputString = [[[NSString alloc] initWithData:outputData encoding:NSUTF8StringEncoding] autorelease]; 

を、それはそのようなファイルやディレクトリを言わないが、私はターミナルでこれを行う場合:

私はこれを試してみました

ioreg -c BNBMouseDevice | grep BatteryPercent 

は、それが動作します!

何が問題なのですか。

+0

ここでは、この種のことを行うために 'NSTask'と' NSPipe'を既に使用している例がたくさんあります。 http:// stackoverflow。com/questions/3444178/nstask-nspipe-objective-c-command-line-help –

+0

こんにちはこれを試してみました:NSTask * server = [NSTask new]; \t [server setLaunchPath:@ "/ bin/sh"]; \t [サーバー配列のアーギュメント:[NSArray arrayWithObject:@ "ioreg -c BNBMouseDevice | grep BatteryPercent"]]; \t \t NSPipe * outputPipe = [NSPipe pipe]; \t [サーバーのsetStandardInput:[NSPipeパイプ]]; \t [サーバーsetStandardOutput:outputPipe]; \t \t [サーバーの起動]; \t [server waitUntilExit]; \t [サーバーのリリース]; \t \t NSData * outputData = [[outputPipe fileHandleForReading] readDataToEndOfFile]; \t NSString * outputString = [[NSString alloc] initWithData:outputDataエンコーディング:NSUTF8StringEncoding] autorelease]; – cocos2dbeginner

+0

しかし、このようなファイルやディレクトリはありませんが、私は端末でこれを行う場合:ioreg -c BNBMouseDevice | grep BatteryPercent //動作します!何が間違っていますか? – cocos2dbeginner

答えて

2

/bin/shを呼び出すときに、シェルにコマンドを実行させる場合は、-cを渡す必要があります。私は2つの変更を加えました

[server setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/sbin/ioreg -c BNBMouseDevice | /usr/bin/grep BatteryPercent", nil]]; 

お知らせして

[server setArguments:[NSArray arrayWithObject:@"ioreg -c BNBMouseDevice | grep BatteryPercent"]]; 

を置き換えることによって、あなたはこれを行うことができます

/bin/sh -c "/usr/sbin/ioreg -c BNBMouseDevice | /usr/bin/grep BatteryPercent" 

:それは同等にする必要があり、引数が2と配列されていますつまり、 "-c"と "/ usr/sbin/ioreg -c BNBMouseDevice |/usr/bin/grep BatteryPercent"となりました。また、ioreg/usr/sbin/ioregに置き換えました(grepは/usr/bin/grep)、あなたがそれらの特定のプログラムに興味があることを明示してください。

+0

これは出力として得られます:http://pastie.org/1437941私はnsdictを作って、これを作るべきです:valueForKey:BatteryPercent "?助けてください(私はすでに正しい答えとしてマークしています) – cocos2dbeginner

+0

しかし、これはうまくいきませんが、私は "BatteryPercent"だけが欲しいのですが、どうすればいいですか?(最初に私は正解としてそ​​れをチェックします);) – cocos2dbeginner

+0

私の知る限り、あなたはその出力を直接NSDictionaryに変換してください(恐らくNeXTスタイルのプロパティリスト形式で、文字をトリミングする必要があります)。可能な解決策の1つは、grepの呼び出しを 'grep '\" BatteryPercent \ "= 0-9] "' '' BatteryPercent "='に続いて数字だけが一致するようにし、 '' grep '\ "BatteryPercent \" = [0-9] "のように' cut'にパイプします。 txt | cut -d = -f2'(適切なエスケープあり)ですが、これはやや壊れやすく、IMOは 'ioreg'を実行する代わりにAPI(IOKit?)を使って置き換えるべきです。 –

3

NSTaskは、一連の引数を文字列の配列として受け取る単一のコマンドを起動します。 NSTaskは、シェル構文解析の魔法を実行せず、文字列を引数としてshに渡すことも、そのように解析することもできません。これを行う方法はおそらくありますが、より良い解決法があります。

NSTaskioregコマンドを実行し、標準的な方法で出力を取得し、返された文字列を単純に列挙して、必要な行を探します。いくつかのコード行がありますが、シェルを介してポンピングしようとするよりも、かなり壊れにくくなります(いくつかの引数を指定するとセキュリティホールが少なくなります)。そしてそれは簡単です。

詳細については、this documentを参照してください。

+0

コードを教えていただけませんか? – cocos2dbeginner

関連する問題