NSTask get the output of a command - objective-c

I am trying to run an executable on OS X from one of the other application.
NSPipe *pipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
task.arguments = #[#"param1", #"param2", #"param3", #"param4"];
task.launchPath = #"/usr/bin/myApp";
[task setStandardOutput: pipe];
[task launch];
[task waitUntilExit];
NSFileHandle *file = [pipe fileHandleForReading];
NSData *output = [file readDataToEndOfFile];
NSString *outputString = [[NSString alloc] initWithData:output encoding:NSUTF8StringEncoding];
[file closeFile];
NSLog(#"%#",outputString);`
But the output is nothing. Though, I am sure NSTask is getting executed. I think I am doing something wrong with NSPipe. But I am still not seeing the expected output.
Thanks.

Related

See NSTask output Cocoa

How could I make an if statement that's like:
if(the output of a nstask is equal to a specific string){
//do stuff over here
}
I'm running a NSTask and it put's out the data that's coming from it in the NSLog, but how could I not show it there but store it as a NSString or something like that
This is what my task looks like
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/usr/bin/csrutil"];
[task setArguments:#[ #"status" ]];
[task launch];
Any help is greatly appreciated :)
You need a pipe and a file handle to read the result.
Write a method
- (NSString *)runShellScript:(NSString *)cmd withArguments:(NSArray *)args
{
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:cmd];
[task setArguments:args];
NSPipe *pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file = [pipe fileHandleForReading];
[task launch];
NSData *data = [file readDataToEndOfFile];
return [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
}
and call it
NSString *result = [self runShellScript:#"/usr/bin/csrutil" withArguments:#[ #"status" ]];

Launching command using NSTask returns error

I'd like to launch the following command from my application using NSTask:
sudo -u myusername launchctl load /Library/LaunchAgents/com.google.keystone.agent.plist
Here is a code I do:
NSPipe *pipe = [NSPipe pipe];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/sh"];
[task setCurrentDirectoryPath:#"/"];
[task setStandardError:pipe];
NSArray *arguments = nil;
arguments = #[#"sudo",
#"-u",
#"myusername",
#"launchctl",
#"load",
#"/Library/LaunchAgents/com.google.keystone.agent.plist"];
[task setArguments: arguments];
NSFileHandle * read = [pipe fileHandleForReading];
[task launch];
[task waitUntilExit];
NSData * dataRead = [read readDataToEndOfFile];
NSString * output = [[NSString alloc] initWithData:dataRead encoding:NSUTF8StringEncoding];
NSLog(#"output: %#", output);
After processing I receive an error below:
/bin/sh: sudo: No such file or directory
I've found out solution:
arguments = #[#"-c",
#"sudo -u myusername launchctl load /Library/LaunchAgents/com.google.keystone.agent.plist"];

How to run sudo command programmatically on OS X

I am trying to run sudo command programmatically in my OS X app,
but i got these message
sudo: no tty present and no askpass program specified
Here is my code:
NSString *runCommand(NSString *commandToRun)
{
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/sh"];
NSArray *arguments = [NSArray arrayWithObjects:#"-c" ,[NSString stringWithFormat:#"%#", commandToRun], nil];
NSLog(#"run command: %#",commandToRun);
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
NSData *data;
data = [file readDataToEndOfFile];
NSString *output;
output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
return output;
}
And i call this method like this :
runCommand(#"sudo purge");
Thanks for any help or sugession.

NSTask File Path Converting Into ShellPath?

I have a Mac (not iOS) application. I want to run a shell command 'find' after the user selects a folder with NSOpenPanel. The following is what I have.
NSString *path = [url path];
NSString *folderName = [path lastPathComponent];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/usr/bin/find"];
NSMutableString *command = [[NSMutableString alloc] initWithString:path];
[command appendString:#" -name '._*' -type f "];
NSArray* args = [NSArray arrayWithObjects:#"commit",command,nil];
[task setArguments:args];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
[task launch];
NSFileHandle *file;
file = [pipe fileHandleForReading];
NSData *data;
data = [file readDataToEndOfFile];
NSString *output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"%#",output);
It's my first time running a shell command with a Mac application that is developed with Objective-C. I suppose that I'm on the right track. Anyway, when I select a folder, I get the following debugger output message.
find: commit: No such file or directory
find: find: /Volumes/SDHC 16 GB/More -name '._*' -type f : No such file or directory
I suppose that the shell command cannot read this sort of file paths. Do I need to convert it into a shell path or whatever it understand? If so, how?
Thank you for your advice.
I got it.
NSString *path = [url path];
NSString *folderName = [path lastPathComponent];
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/usr/bin/find"];
NSMutableString *command = [[NSMutableString alloc] initWithString:#""];
[command appendString:#" -name '._*' -type f"];
NSArray* args = [NSArray arrayWithObjects:path,command,nil];
[task setArguments:args];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
[task launch];
NSFileHandle *file;
file = [pipe fileHandleForReading];
NSData *data;
data = [file readDataToEndOfFile];
NSString *output = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"%#",output);

NSTask and FFMpeg losing output

I'm trying to call ffmpeg from NSTask in objective-c. I execute the ffmpeg command in terminal and it works flawlessly every time. I make the same command using NSTask, and it never gives me the whole output. It cuts it off half way through the output, at a seemingly random spot every time. Here is my code.
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSString* ffmpegPath = [[NSBundle mainBundle] pathForResource:#"ffmpeg" ofType:#""];
NSString* path = #"test.mov";
NSTask *task = [[NSTask alloc] init];
NSArray *arguments = [NSArray arrayWithObjects: #"-i", path, nil];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle * read = [pipe fileHandleForReading];
[task setLaunchPath: ffmpegPath];
[task setArguments: arguments];
[task setStandardOutput: pipe];
[task launch];
[task waitUntilExit];
NSData* data = [read readDataToEndOfFile];
NSString* stringOutput = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", stringOutput);
NSLog(#"%i", [task terminationStatus]);
NSLog(#"DONE");
}
And just like that I figured it out. Apparently the output had non UTF8Characters in it. Switched it over to NSASCIIStringEncoding and voila. Magic.