2011-01-07 1 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 [서버 setLaunchPath : @ "/ bin/sh"]; \t [serverArray : 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을 전달해야합니다. 나는이 변경 한

[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" 

: 그것은 동등한에 있어야한다 인수가 두와 배열이다 즉 "-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"='뒤에 숫자를 붙여서''grep "\"BatteryPercent \ "= [0-9]"와 같이'cut '으로 파이프하도록 c. txt | cut -d = -f2' (적절하게 이스케이프 처리). 그러나 이는 매우 약해 보이고 IMO는 ioreg를 실행하는 대신 API (IOKit?)를 사용하여 대체해야합니다. –

3

NSTask은 인수 집합을 문자열 배열로 취하는 단일 명령을 실행합니다. NSTask은 셸 구문 분석 마법을 수행하지 않으며 문자열을 sh에 인수로 전달하여 해당 구문으로 구문 분석 할 수도 없습니다. 그렇게 할 수있는 방법이 있지만 더 나은 해결책이 있습니다.

NSTask을 통해 ioreg 명령을 실행하고 표준 방법을 통해 출력물을 가져온 다음 반환 된 문자열을 간단한 열거하여 원하는 행을 찾으십시오. 몇 줄의 코드가 있지만 쉘을 통해 펌프를 펌핑하는 것보다 훨씬 취약 할 수 있습니다 (그리고 어떤 종류의 인수를 제공하는 경우 보안 구멍이 적음). 그리고 그것은 쉽게 할 수 있습니다.

자세한 내용은 this document을 참조하십시오.

+0

코드 몇 개를 줄 수 없습니까? – cocos2dbeginner