2011-01-07 2 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

Существует много примеров здесь, на SO, уже использующих 'NSTask' и' NSPipe', чтобы делать такие вещи, например. Http: // StackOverflow.com/questions/3444178/nstask-nspipe-objective-c-command-line-help –

+0

Привет: это NSTask * server = [NSTask new]; \t [серверный комплектLaunchPath: @ "/ bin/sh"]; \t [server setArguments: [NSArray arrayWithObject: @ "ioreg -c BNBMouseDevice | grep BatteryPercent"]]; \t \t NSPipe * outputPipe = [труба NSPipe]; \t [server 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 encoding: NSUTF8StringEncoding] autorelease]; – cocos2dbeginner

+0

, но в нем нет такого файла или каталога, но если я делаю это в терминале: ioreg -c BNBMouseDevice | grep BatteryPercent // это работает! Что случилось? – cocos2dbeginner

ответ

2

При вызове /bin/sh вам необходимо передать -c, если вы хотите, чтобы оболочка запускала команду. Это должно быть эквивалентно:

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

Вы можете сделать это, заменив

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

с

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

Обратите внимание, что я сделал два изменения: аргументы массив с двумя элементы, а именно «-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

, поэтому я попытался сделайте dict, но это не сработает, но я просто хочу «BatteryPercent». Как я могу это получить? (сначала скажите мне, что и я буду указывать его как правильный ответ);) – cocos2dbeginner

+0

Насколько я знаю, вы не можете преобразуйте этот вывод непосредственно в NSDictionary (возможно, в формате списка свойств стиля NeXT, и вам все равно нужно обрезать символы |). Одно из возможных решений - изменить ваш вызов grep на 'grep '\" BatteryPercent \ "= [ 0-9] ", так что он будет соответствовать только« BatteryPercent »=', а затем цифра, и передать его на 'cut', например' grep '\ "BatteryPercent \" = [0-9] "c. txt | cut -d = -f2' (с правильным экранированием). Однако это кажется довольно хрупким, и IMO следует заменить с помощью API (IOKit?) вместо запуска 'ioreg'. –

3

NSTask запускает единственную команду, которая принимает набор аргументов в виде массива строк. NSTask не выполняет никакой магии разбора оболочки и не может передать строку в sh в качестве аргумента и проанализировать ее таким образом. Вероятно, есть способ сделать это, но есть лучшее решение.

Просто запустите команду ioreg через NSTask, возьмите выход через стандартные средства, затем выполните простой перечисление возвращаемой строки, чтобы найти нужную вам линию. В то время как еще несколько строк кода, он будет значительно менее хрупким (и меньше дыры в безопасности, если вы когда-нибудь будете давать какие-либо аргументы), чем пытаться прокачать его через оболочку. И это легко сделать.

Для получения дополнительной информации см. this document.

+0

Вы не можете дать мне код? – cocos2dbeginner

Смежные вопросы