Execute terminal command top from a Cocoa app
I want to execute top and get the result in order to know how much memory is used by a process.
First, I want to execute a terminal command. I use code from this question Execute a terminal command from a Cocoa app
I tried with uptime and it worked flawlessly.
But, when I tried to use top instead of uptime, i get the following error:
Error opening termi开发者_高级运维nal: unknown.
Or, top is in /usr/bin/top, I don't know why it refuses to use it.
Here is my code:
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/usr/bin/top"];
/*NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"foo", @"bar.txt", 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];
[label setStringValue: string];
[string release];
[task release];
Second question: the thing I am trying to do is to know how much memory is used by Google Chrome. Because it uses a process for each tab, it's difficult to know how much memeroy in total it uses.
Problem 1: top changes its value every second, how can I get a value? Problem 2: how can I search in the result of top in order to find only the processes I want (given that I know their names).
Thanks.
The problem is that commands like top needs a terminal (= window to interact with) to execute.
This means they need a real window context, because they display the results dynamically in the window (clearing the window, displaying the output of "top" in the whole terminal window, and more important, update the display every N seconds, redrawing the whole terminal window)
So as commands like top
need a real "Terminal", this is why, when using top
with NSTask
, it throw "Error opening terminal".
You may instead check in the manual page of top (man top
) if there is an option to avoid dynamic paging of the command and instead output a single shot (without using ncurse and the terminal dynamic display) directly on stdout (maybe try top -l 1
-- Don't have my Mac here to try myself and confirm).
Or a better solution is probably to dig around commands like ps
(or others?) instead of top
that will give you the same info but directly on stdout instead of as a dynamic display in a terminal.
For your first question, use the arguments for top. For example
top -l 1
This will give one set of output.
Hence in the code:
NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"-l 1", nil];
[task setArguments: arguments];
This will successfully execute the NSTask.
For non interactive operations with process information, I would use ps
instead of top
.
精彩评论