prabhu
prabhu

Reputation: 1216

NSTask standardOutput for "cd" command - Cocoa Objective C

I am trying to use NSTask to execute terminal commands using the standardInput and standardOutput. Everything works for commands like ls, pwd, etc. But When I try to run cd command, Standard output doesn't write any output. I understand that standardOutput won't write any data since cd command doesn't have any response to display. But Is there anyway to check if the command has run successfully? I need this as I am waiting for a response to update the UI. Below is my code. I am using NSFileHandleDataAvailableNotification to read the output as this helps with commands like ping

-(void)setupTask {
    @autoreleasepool {
        // Commands are read from standard input:
        NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
        
        NSPipe *inPipe = [NSPipe new]; // pipe for shell input
        NSPipe *outPipe = [NSPipe new]; // pipe for shell output
        NSPipe *errorPipe = [NSPipe new];
        
        task = [NSTask new];
        [task setLaunchPath:@"/bin/sh"];
        [task setStandardInput:inPipe];
        [task setStandardOutput:outPipe];
        [task setStandardError:errorPipe];
        
        [task launch];
        
        // Wait for standard input ...
        [input waitForDataInBackgroundAndNotify];
        // ... and wait for shell output.
        [[outPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
        [[errorPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
        
        
        // Wait asynchronously for standard input.
        // The block is executed as soon as some data is available on standard input.
        [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
                                                          object:input queue: [NSOperationQueue mainQueue]
                                                      usingBlock:^(NSNotification *note)
         {
            NSData *inData = [input availableData];
            if ([inData length] == 0) {
                // EOF on standard input.
                [[inPipe fileHandleForWriting] closeFile];
            } else {
                // Read from standard input and write to shell input pipe.
                [[inPipe fileHandleForWriting] writeData:inData];
                
                // Continue waiting for standard input.
                [input waitForDataInBackgroundAndNotify];
            }
        }];
        
        // Wait asynchronously for shell output.
        // The block is executed as soon as some data is available on the shell output pipe.
        [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
                                                          object:[outPipe fileHandleForReading] queue:[NSOperationQueue mainQueue]
                                                      usingBlock:^(NSNotification *note)
         {
            // Read from shell output
            NSData *outData = [[outPipe fileHandleForReading] availableData];
            if ([outData length] > 0) {
                NSString *outStr = [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
                NSLog(@"Output: %@", outStr);
            }
            // Continue waiting for shell output.
            [[outPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
        }];
        
        [[NSNotificationCenter defaultCenter] addObserverForName:NSFileHandleDataAvailableNotification
                                                          object:[errorPipe fileHandleForReading] queue:[NSOperationQueue mainQueue]
                                                      usingBlock:^(NSNotification *note)
         {
            // Read from shell output
            NSData *outData = [[errorPipe fileHandleForReading] availableData];
            if ([outData length] > 0) {
                NSString *outStr = [[NSString alloc] initWithData:outData encoding:NSUTF8StringEncoding];
                    NSLog(@"Error: %@", outStr);
            }
            // Continue waiting for shell output.
            [[errorPipe fileHandleForReading] waitForDataInBackgroundAndNotify];
        }];
    }
}

-(void)executeCommand:(NSString*)command {
    
    NSData* data = [command dataUsingEncoding:NSUTF8StringEncoding];
    NSError* error;
    [[[task standardInput] fileHandleForWriting] writeData:data error:&error];
    if (error != NULL) {
        NSLog(@"%@", [error localizedDescription]);
    }
    
    NSData* newLine = [@"\n" dataUsingEncoding:NSUTF8StringEncoding];
    [[[task standardInput] fileHandleForWriting] writeData:newLine error:&error];
    if (error != NULL) {
        NSLog(@"%@", [error localizedDescription]);
    }
}

-(void)runCommand {
    [self setupTask];
    [self executeCommand:@"cd Users"];
}

Upvotes: 0

Views: 59

Answers (0)

Related Questions