0

I'm trying to determine if a particular process if running, and tried with NSTask but it gives me an error when I try to grep the ps command: ps: illegal argument: |.

Maybe trying to use nstask for this is not the best way?

Here is the my code:

NSString *process = @"grep \"/usr/sbin/notifyd\"";

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

NSArray *arguments;
arguments = [NSArray arrayWithObjects:@"ax",process,nil]; // works, but returns all processes
// arguments = [NSArray arrayWithObjects:@"ax", @"|", process,nil]; // returns illegal argument

[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 (@"result:\n%@", string);

I'm looking to return one line (if process is active) to let me know if the process is running. This is a mac application, and it is not sandboxed. thanks..

  • 1
    You cannot pipe multiple commands like in Terminal.app. You need a second `NSTask` and pass the result of the first to standard input. – vadian May 02 '17 at 19:13
  • @vadian: That's what I thought, but wasn't sure. The problem with the second NSTask though is it never finishes. It seems to hang when trying to grep the result of the first task. Is nstask the best way? – Niko Federov May 02 '17 at 19:18
  • There are C functions (in `sysctl`) to get the pid for a process name which can also check if this particular process is running. – vadian May 02 '17 at 19:26
  • @vadian: I found another way i believe using `kinfo_proc`, thanks. – Niko Federov May 02 '17 at 19:36

1 Answers1

0

You do not need a second task to solve this, as has been suggested, consider what you are attempting - to run a shell command line, and what runs shell command lines?

Look up sh in the manual and you'll see you can pass it a complete command line, including pipes, redirection, etc. as an argument. Now use NSTask to run the shell passing the appropiriate arguments.

You can also use the C library system, popen etc. functions to do the same job.

That said you might want to avoid using shell commands for this, consider for example NSWorkspace's runningApplications method.

Addendum

Now I'm not on a tablet... Here is your code modified to use the shell:

NSTask *task = [NSTask new];

task.launchPath = @"/bin/sh";
task.arguments = @[@"-c", @"ps -ax | grep /usr/bin/notifyd"];

NSPipe *pipe = [NSPipe pipe];
task.standardOutput = pipe;

NSFileHandle *file = [pipe fileHandleForReading];

[task launch];

NSData *data = [file readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (@"result:\n%@", string);

You of course will get one or two lines which match, as a line for grep will always be there. Why not just run ps -ax and then use NSString's containsString:? So:

task.launchPath = @"/bin/ps";
task.arguments = @[@"-ax"];

and then something like:

NSData *data = [file readDataToEndOfFile];
NSString *string = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
BOOL notifydIsRunning = [string containsString:@"/usr/sbin/notifyd"];
NSLog (@"notifydIsRunning: %@", notifydIsRunning ? @"yes" : @"no");

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • 1
    `runningApplications` won't work unless it's an application bundle I don't think will it? – Niko Federov May 03 '17 at 15:31
  • @NikoFederov - Apologies I didn't note you were searching for `notifyd`, so `runningApplications` is not an option. I've added an addendum with code showing how to the the shell, or avoid it... – CRD May 03 '17 at 19:26