【问题标题】:NSTask to check if process is runningNSTask 检查进程是否正在运行
【发布时间】:2017-05-02 19:07:00
【问题描述】:

我正在尝试确定某个特定进程是否正在运行,并尝试使用NSTask,但是当我尝试使用 grep ps 命令时,它给了我一个错误:ps: illegal argument: |

也许尝试为此使用 nstask 不是最好的方法?

这是我的代码:

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);

我希望返回一行(如果进程处于活动状态)让我知道进程是否正在运行。这是一个 mac 应用程序,它没有沙盒。谢谢..

【问题讨论】:

  • 您不能像在 Terminal.app 中那样通过管道传输多个命令。您需要第二个 NSTask 并将第一个的结果传递给标准输入。
  • @vadian:我就是这么想的,但不确定。第二个 NSTask 的问题是它永远不会完成。尝试 grep 第一个任务的结果时,它似乎挂起。 nstask 是最好的方法吗?
  • 有 C 函数(在 sysctl 中)可以获取进程名称的 pid,它还可以检查该特定进程是否正在运行。
  • @vadian:我发现了另一种我相信使用kinfo_proc的方法,谢谢。

标签: objective-c macos cocoa nstask


【解决方案1】:

您不需要第二个任务来解决这个问题,正如建议的那样,考虑一下您正在尝试什么 - 运行 shell 命令行,以及运行 shell 命令行的内容是什么?

在手册中查找sh,您会看到您可以将完整的命令行(包括管道、重定向等)作为参数传递给它。现在使用NSTask 运行传递适当参数的shell。

您还可以使用 C 库 systempopen 等函数来完成相同的工作。

也就是说,您可能希望避免为此使用 shell 命令,例如考虑 NSWorkspacerunningApplications 方法。

附录

现在我不在平板电脑上...这是您的代码修改为使用外壳:

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);

您当然会得到一两行匹配的行,因为grep 的行将始终存在。为什么不直接运行ps -ax,然后使用NSStringcontainsString:?所以:

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

然后是这样的:

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

【讨论】:

  • runningApplications 将无法工作,除非它是我认为不会的应用程序包?
  • @NikoFederov - 抱歉,我没有注意到您正在搜索 notifyd,所以 runningApplications 不是一个选项。我添加了一个附录,其中包含显示如何使用 shell 的代码,或者避免它......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-05-28
  • 1970-01-01
  • 2020-05-03
  • 2017-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多