2012-06-15 26 views
8

Ok, vì vậy tôi biết bạn có thể làm cho một NSTask để chạy công cụ dòng lệnh với Objective-C:Cocoa wrapper cho một lệnh tương tác Unix

NSTask *task; 
task = [[NSTask alloc] init]; 
[task setLaunchPath: @"/usr/bin/gdb"]; 
[task launch]; 

Tôi chỉ tự hỏi nếu có một cách để giao tiếp với tương tác các công cụ dòng lệnh như gdb. Điều này sẽ liên quan đến việc đưa ra các đầu vào lệnh dựa trên tương tác của người dùng (như run, kill hoặc quit với gdb) và sau đó phản ứng dựa trên thông tin mà nó xuất ra.

Trả lời

2

Bạn có thể sử dụng các bộ chọn setStandardInput:, setStandardOutput:setStandardError: của NSTask cùng với các trường hợp NSPipe để liên lạc với chương trình được khởi chạy.

Ví dụ, để đọc kết quả của nhiệm vụ:

task = [[NSTask alloc] init]; 
[task setStandardOutput: [NSPipe pipe]]; 
[task setStandardError: [task standardOutput]]; // Get standard error output too 
[task setLaunchPath: @"/usr/bin/gdb"]; 
[task launch]; 

Sau đó bạn có thể có được một NSFileHandle dụ mà bạn có thể sử dụng để đọc kết quả của nhiệm vụ với:

NSFileHandle *readFromMe = [[task standardOutput] fileHandleForReading]; 

Để thiết lập một đường ống để gửi lệnh tới gdb, bạn sẽ thêm

[task setStandardInput: [NSPipe pipe]]; 

trước bạn khởi chạy tác vụ. Sau đó, bạn sẽ có được NSFileHandle với

NSFileHandle *writeToMe = [[task standardInput] fileHandleForWriting]; 
+0

Chúc mừng! Bạn sẽ sử dụng một cái gì đó như 'NSData * data = [inString dataUsingEncoding: NSUTF8StringEncoding]; [writeToMe writeData: data]; 'để gửi lời khen? Tôi đã thử nó nhưng nó dường như không hoạt động. – bjz

+3

@bjz Điều đó sẽ hiệu quả. Đừng quên chắp thêm một '\ n' vào cuối chuỗi để mô phỏng người dùng nhấn trở lại sau khi gõ lệnh. – sjs

2

Sử dụng setStandardInput:setStandardOutput: phương pháp NSTaks class.

NSTask *task; 
task = [[NSTask alloc] init]; 
[task setLaunchPath: @"/usr/bin/gdb"]; 

NSPipe *outputpipe=[[NSPipe alloc]init]; 
NSPipe *errorpipe=[[NSPipe alloc]init]; 
NSFileHandle *output,*error; 

[task setArguments: arguments]; 
[task setStandardOutput:outputpipe]; 
[task setStandardError:errorpipe]; 

NSLog(@"%@",arguments); 

output=[outputpipe fileHandleForReading];  
error=[errorpipe fileHandleForReading];  
[task launch]; 

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedData:) name: NSFileHandleReadCompletionNotification object:output]; 
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedError:) name: NSFileHandleReadCompletionNotification object:error];  
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(TaskCompletion:) name: NSTaskDidTerminateNotification object:task]; 

//[input writeData:[NSMutableData initWithString:@"test"]]; 
[output readInBackgroundAndNotify]; 
[error readInBackgroundAndNotify]; 

[task waitUntilExit]; 
[outputpipe release]; 
[errorpipe release]; 
[task release]; 

-(void) receivedData:(NSNotification*) rec_not { 
    NSFileHandle *out=[[task standardOutput] fileHandleForReading]; 
    NSData *dataOutput=[[rec_not userInfo] objectForKey:NSFileHandleNotificationDataItem]; 

    if(!dataOutput) 
     NSLog(@">>>>>>>>>>>>>>Empty Data"); 

    NSString *strfromdata=[[NSString alloc] initWithData:dataOutput encoding:NSUTF8StringEncoding];  
    [out readInBackgroundAndNotify]; 
    [strfromdata release]; 
} 

/* Called when there is some data in the error pipe */ 
-(void) receivedError:(NSNotification*) rec_not { 
    NSFileHandle *err=[[task standardError] fileHandleForReading]; 
    NSData *dataOutput=[[rec_not userInfo] objectForKey:NSFileHandleNotificationDataItem]; 

    if(!dataOutput)  
     NSLog(@">>>>>>>>>>>>>>Empty Data"); 
    else { 
     NSString *strfromdata=[[NSString alloc] initWithData:dataOutput encoding:NSUTF8StringEncoding]; 
    [strfromdata release]; 
    } 
    [err readInBackgroundAndNotify]; 
} 

/* Called when the task is complete */ 
-(void) TaskCompletion :(NSNotification*) rec_not { 
    NSLog(@"task ended"); 
} 
+0

Xin chào, bạn đã nhận công việc này chưa? Tôi dường như có vấn đề thực hiện điều này. Tôi không nhận được bất kỳ thông báo nào. Tôi đang sử dụng điều này để thực hiện một bản sao git. Tôi cần thông báo để cho tôi biết khi nào tôi hỏi tên người dùng và mật khẩu. Bất kỳ giúp đỡ? –

Các vấn đề liên quan