How to run NSTask with multiple commands

nstask launch deprecated
nstask example
nstask run shell command
nstask objective c
nstask ios
swift process
nstask run terminal command
nstask setarguments

I'm trying to make a NSTask running a command like this:

ps -clx | grep 'Finder' | awk '{print $2}'

Here is my method

- (void) processByName:(NSString*)name {
    NSTask *task1 = [[NSTask alloc] init];
    NSPipe *pipe1 = [NSPipe pipe];
    [task1 waitUntilExit];
    [task1 setLaunchPath: @"/bin/ps"];
    [task1 setArguments: [NSArray arrayWithObjects: @"-clx", nil]];
    [task1 setStandardOutput: pipe1];

    NSTask *task2 = [[NSTask alloc] init];
    NSPipe *pipe2 = [NSPipe pipe];
    [task2 setLaunchPath: @"/usr/bin/grep"];
    [task2 setArguments: [NSArray arrayWithObjects: @"'Finder'", nil]];
    [task2 setStandardInput:pipe1];
    [task2 setStandardOutput: pipe2];

    NSTask *task3 = [[NSTask alloc] init];
    NSPipe *pipe3 = [NSPipe pipe];
    [task3 setLaunchPath: @"/usr/bin/grep"];
    [task3 setArguments: [NSArray arrayWithObjects: @"'{print $2}'", nil]];
    [task3 setStandardInput:pipe2];
    [task3 setStandardOutput: pipe3];

    NSFileHandle *file = [pipe3 fileHandleForReading];

    [task1 launch];
    [task2 launch];
    [task3 launch];

    NSData *data;
    data = [file readDataToEndOfFile];

    NSString *string;
    string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];

    NSLog(@"Result: %@", string);
}

But the result is just

Result:

What am I doing wrong?

EDIT

- (void) processByName:(NSString*)name {
    NSTask *task1 = [[NSTask alloc] init];
    NSPipe *pipe1 = [NSPipe pipe];
    [task1 waitUntilExit];
    [task1 setLaunchPath: @"/bin/ps"];
    [task1 setArguments: [NSArray arrayWithObjects: @"-clx", nil]];
    [task1 setStandardOutput: pipe1];

    NSTask *task2 = [[NSTask alloc] init];
    NSPipe *pipe2 = [NSPipe pipe];
    [task2 setLaunchPath: @"/usr/bin/grep"];
    [task2 setArguments: [NSArray arrayWithObjects: @"'Finder'", nil]];
    [task2 setStandardInput:pipe1];
    [task2 setStandardOutput: pipe2];

    NSTask *task3 = [[NSTask alloc] init];
    NSPipe *pipe3 = [NSPipe pipe];
    [task3 setLaunchPath: @"/usr/bin/grep"];
    [task3 setArguments: [NSArray arrayWithObjects: @"'{print $2}'", nil]];
    [task3 setStandardInput:pipe2];
    [task3 setStandardOutput: pipe3];

    NSFileHandle *file = [pipe3 fileHandleForReading];

    [task1 launch];
    [task2 launch];
    [task3 launch];

    [[NSNotificationCenter defaultCenter] addObserverForName:NSTaskDidTerminateNotification
                                                      object:task3
                                                       queue:nil
                                                  usingBlock:^(NSNotification* notification){

                                                      NSData * data = [file readDataToEndOfFile];

                                                      NSString * string;
                                                      string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
                                                      NSLog(@"Result: %@", string);
                                                  }];
}

The tasks run in a separate process from your code, i.e., asychronously. They probably haven't finished (they may not have even launched!) by the time you get to the readDataToEndOfFile two lines later.

If you're already on a background thread here, you can poll their status: while( ![task isRunning]){, or if you're on the main thread, I'd suggest using GCD to put this onto a queue and doing the polling there.

Actually, better than that would be to use notifications:

[task3 launch];

[[NSNotificationCenter defaultCenter] addObserverForName:NSTaskDidTerminateNotification
                                                  object:task3
                                                   queue:nil
                                              usingBlock:^{

    NSData * data = [file readDataToEndOfFile];

    NSString * string;
    string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];

    NSLog(@"Result: %@", string);
}];

See TN2050: Observing Process Lifetime Without Polling. Each NSTask will send NSTaskDidTerminateNotification when it terminates (you should, ideally, check its return code rather than assuming it ran successfully). You can create a block to be run when task3 sends that notification.

Multiple Commands with NSTask, I want to run a shell script using NSTask. This script is designed such that it will first come out from its current operation (cd ..) then will perform� Using the NSTask class, your program can run another program as a subprocess and can monitor that program’s execution. A NSTask object creates a separate executable entity; it differs from NSThread in that it does not share memory space with the process that creates it.


The following code works for me.

NSTask *task1 = [[NSTask alloc] init];
NSPipe *pipe1 = [NSPipe pipe];
[task1 waitUntilExit];
[task1 setLaunchPath: @"/bin/sh"];
[task1 setArguments: [NSArray arrayWithObjects: @"-c",@"ps -A |grep -m1 Finder | awk '{print $1}'", nil]];
[task1 setStandardOutput: pipe1];
[task1 launch];

NSFileHandle *file = [pipe1 fileHandleForReading];
NSData * data = [file readDataToEndOfFile];

NSString * string;
string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(@"Result: %@", string);

Quickies for NSTask, Here are the basics to launch "ls -l -a -t" in the current directory, and then read You can create multiple NSTasks and a bunch of NSPipes and hook them together, or you can use the " sh -c " trick to feed a shell a command, and let it parse it� 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,


Almost 8 years later, I think grep binary is'nt in /usr/bin, for me it's in /bin. Also, for your awk command, you set the launch path to grep.

Nstask – Eon's swift blog, NSTask lets you run command-line calls in your app My initial quest was to find a way to call multiple command line calls in one NSTask, But� NSTask allows you to execute another program on your machine as a subprocess and monitor its execution state while your main program continues to run. For example, you could run the ls command to display a directory listing — from right inside your app! A good analogy for NSTask is a parent-child relationship. A parent can create a child and


NSTask Tutorial for OS X, A great use for NSTask is to provide a front-end GUI to command line If you run the script multiple times, you'll want to clear it out between� The semicolon (;) operator allows you to execute multiple commands in succession, regardless of whether each previous command succeeds. For example, open a Terminal window (Ctrl+Alt+T in Ubuntu and Linux Mint). Then, type the following three commands on one line, separated by semicolons, and press Enter.


NSTask Sample for Swift � GitHub, var task:NSTask = NSTask() Create a Task instance (was NSTask on swift pre 3.0) let task is it possible to run multiple commands? Bind Multiple commands to Tkinter Button. The Tkinter button has only one command property so that multiple commands or functions should be wrapped to one function that is bound to this command. We could use lambda to combine multiple commands as, command=lambda:[funcA(), funcB(), funcC()] This lambda function will execute funcA, funcB, and


objective c - Trying to run NSTask but getting an error, Many multi-user operating systems provide ways for any user to see the current command line of any other user; even on stand-alone systems there is always� Try to read some information from system profiler. For this purpose i m running some terminal line commands with NSTask. If i run some command which