NSTask: using multiple pipes for multiple commands

Discussion in 'Mac Programming' started by pcwiz, Aug 1, 2009.

  1. pcwiz macrumors member

    Joined:
    May 28, 2008
    #1
    I read about 2 methods to run commands like these:

    Code:
    otool -L /Applications/TextEdit.app/Contents/MacOS/TextEdit  | awk 'NR>1{print $1}' | sed -e '/@executable_path/d' -e 's/(.*)$//' -e  's/\/Versions.*$//'
    Where multiple commands are combined using pipes. I read about the /bin/sh way where you set the launch path to /bin/sh, the first argument to @"-c", second argument to whatever your command is, and then the 3rd argument to nil (as usual with NSTask). This way did not work for me and did not return an output.

    I also read that you can set each command and its arguments individually and then combine them together with multiple NSPipe objects. However, I am confused as to how I would go about doing this. Any help would be appreciated. Thanks :)
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    This might be cheating, but you could just take the command, stick it in a .sh file, and run that instead.

    -Lee
     
  3. pcwiz thread starter macrumors member

    Joined:
    May 28, 2008
    #3
    Thanks for the suggestion. I created a sh script file with my command and 1 argument ($1):

    Code:
    #!/bin/sh
    
    # Machine readable output of otool
    
    otool -L $1  | awk 'NR>1{print $1}' | sed -e '/@executable_path/d' -e 's/(.*)$//' -e  's/\/Versions.*$//'
    
    And here's my NSTask method:

    Code:
    	NSTask *task;
        task = [[NSTask alloc] init];
        [task setLaunchPath: @"/bin/sh"];
    	
        NSArray *arguments;
        arguments = [NSArray arrayWithObjects: @"/Users/pcwiz/Desktop/beasttool.sh", @"/Applications/TextMate.app/Contents/MacOS/TextMate", nil];
        [task setArguments: arguments];
    	
        NSPipe *pipe;
        pipe = [NSPipe pipe];
        [task setStandardOutput: pipe];
    	
        NSFileHandle *file;
        file = [pipe fileHandleForReading];
    	
        [task launch];
    	
        NSData *data;
        data = [file readDataToEndOfFile];
    	
        NSString *string;
        string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
        NSLog (@"%@", string);
    As you can see I've supplied 3 arguments, the shell script itself, the argument that the script accepts, and the usual "nil". The problem is that this does not return any output. It does return an output when the script is run from Terminal, and I can't figure out the problem.

    EDIT: The NSLog at the end isn't even being called so there does seem to be a problem with something before it. There are no build errors/warnings, and nothing in the console either.

    Thanks

    EDIT2: The "/bin/sh -c" method that people use with NSTask does not work at all for me. I tried a simple ls /Volumes command like this:

    Code:
    - (IBAction)runTask:(id)sender {
    	NSLog(@"hi!");
    	NSTask *task;
        task = [[NSTask alloc] init];
        [task setLaunchPath: @"/bin/sh"];
    	
        NSArray *arguments;
        arguments = [NSArray arrayWithObjects: @"-c", "ls /Volumes", nil];
        [task setArguments: arguments];
    	
        NSPipe *pipe;
        pipe = [NSPipe pipe];
        [task setStandardOutput: pipe];
    	
        NSFileHandle *file;
        file = [pipe fileHandleForReading];
    	
        [task launch];
    	
        NSData *data;
        data = [file readDataToEndOfFile];
    	
        NSString *string;
        string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
        NSLog (@"got\n%@", string);
    }
    
    And it resulted in a crash.
     

Share This Page