How to use NSTask with pbcopy? - objective-c

I am a beginner and I have a problem. I would like to use NSTask with the command "pbcopy". I tried this but it seems that it doesn't work :
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/echo"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: #"my-text-to-copy", #"| pbcopy", nil];
[task setArguments: arguments];
[task launch];
Any ideas ? Thanks.
It works fine :
NSTask *task = [[NSTask alloc] init];
NSPipe *pipe;
pipe = [NSPipe pipe];
task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/echo"];
[task setStandardOutput:pipe]; // write to pipe
[task setArguments: [NSArray arrayWithObjects: #"tmp", nil]];
[task launch];
[task waitUntilExit];
task = [[NSTask alloc] init];
[task setLaunchPath:#"/usr/bin/pbcopy"];
[task setStandardInput:pipe]; // read from pipe
[task launch];
[task waitUntilExit];

The pipe ("|") is a feature of the shell, not an argument to the command you're using. You have to use two NSTasks, one for echo and one for pbcopy and set up an NSPipe between them.
Btw, I'm assuming that you're just using this as an example. Otherwise it would be much simpler to use NSPasteboard for this.

Related

Result of a bash command executed through NSTask

I have this example of using NSTask in Objective-C
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/bash"];
[task setArguments:#[ #"-c", #"cp /Directory/file /users/user_name/Desktop" ]];
[task launch];
I want to know if the [task setArguments:] returns a state of success or failure for executing that command, and save the state to check afterwards. How can I get that result?
I want to know if the [task setArguments:] returns a state of success or failure for executing that command, and save the state to check afterwards.
Why do you think setting the arguments of the task, that is not yet launched and running, might return the status of running the command?
How can I get that result?
Read the documentation for NSTask, its method waitUntilExit, and its property terminationStatus.
That said, as #ItaiFerber raises in the comment, hopefully this is just an example and you are not really using NSTask to run cp.
NSPipe *pipe = [[NSPipe alloc] init];
NSFileHandle *file = pipe.fileHandleForReading;
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/bash"];
[task setArguments:#[ #"-c", #"cp /Directory/file /users/user_name/Desktop" ]];
task.standardOutput = pipe;
[task launch];
if(task.isRunning)
[task waitUntilExit];
int status = [task terminationStatus];
if(status == 0){}

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" ]];

NSTask - execute echo command

I'm trying to run a simple task which has to execute an echo "Hello World"
Well here is my code:
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath:#"/bin/bash"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects:#"echo","hello world" nil];
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
[task setStandardError: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
//...
//Code to get task response
Keep giving me no such file or directory error.. What am I doing wrong ?
The right way to execute a command is
bash -c "echo 'hello world'"
which means the arguments you should pass are
arguments = [NSArray arrayWithObjects:#"-c", #"echo 'hello world'", nil];

Convert NSTask "/bin/sh -c" command into proper pipeline code

Can someone help me convert the following code into code that instead has two NSTasks for "cat" and "grep", showing how the two can be connected together with pipes? I suppose I would prefer the latter approach, since then I no longer have to worry about quoting and stuff.
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/sh"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: #"-c",
#"cat /usr/share/dict/words | grep -i ham", nil];
[task setArguments: arguments];
[task launch];
Update: Note that cat and grep are here just meant as (lousy) example. I still want to do this for commands that make more sense.
Use a instance of NSTask for each program and connect their standard inputs/outputs with NSPipe:
NSPipe *pipe = [[NSPipe alloc] init];
NSPipe *resultPipe = [[NSPipe alloc] init];
NSTask *task1 = [[NSTask alloc] init];
[task1 setLaunchPath: #"/bin/cat"];
[task1 setStandardOutput: pipe];
[task1 launch];
NSTask *task2 = [[NSTask alloc] init];
[task2 setLaunchPath: #"/bin/grep"];
[task2 setStandardInput: pipe];
[task2 setStandardOutput: resultPipe];
[task2 launch];
NSData *result = [[resultPipe fileHandleForReading] readDataToEndOfFile];

NSTask to call command top. Getting Error

intelligent people!
Thanks so much for checking out my post.
Right now I'm running this:
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/usr/bin/top"];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: #"-stats", #"pid,cpu", nil];
[task setArguments: arguments];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
//The magic line that keeps your log where it belongs
[task setStandardInput:[NSPipe pipe]];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
and it is giving me the error:
Error opening terminal: unknown.
Any clues? Thanks again!
It seems as if it was my arguments:
arguments = [NSArray arrayWithObjects: #"-s", #"1",#"-l",#"3600",#"-stats",#"pid,cpu,time,command", nil];
Thanks!