-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathShellTask.m
executable file
·66 lines (50 loc) · 2.26 KB
/
ShellTask.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
//
// ShellTask.m
//
//
// Created by Vincent Gable on 6/1/07.
// Copyright 2007 Vincent Gable, you're free to use this code in *any* way you like, but I'd really appreciate it if you told me what you used it for. It could make my day.
//
#import "ShellTask.h"
@implementation ShellTask
//Returns an NSTask that is equvalent to
// sh -c <command>
//where <command> is passed directly to sh via argv, and is NOT quoted (so ~ expansion still works).
//stdin for the task is set to /dev/null .
//Note that the PWD for the task is whatever the current PWD for the executable sending the taskForCommand: message.
//Sending the task a - launch message will tell sh to run it.
+ (NSTask*) taskForShellCommand:(NSString*)command
{
NSTask *task = [[[NSTask alloc] init] autorelease];
// @"/bin/sh" -> @"/bin/bash"
[task setLaunchPath: @"/bin/bash"]; //we are launching sh, it is wha will process command for us
[task setStandardInput:[NSFileHandle fileHandleWithNullDevice]]; //stdin is directed to /dev/null
NSArray *args = [NSArray arrayWithObjects: @"-c", //-c tells sh to execute commands from the next argument
command, //sh will read and execute the commands in this string.
nil];
[task setArguments: args];
return task;
}
//Executes the shell command, command, waits for it to finish
//returning it's output to std in and stderr.
//
//NOTE: may deadlock under some circumstances if the output gets so big it fills the pipe.
//See http://dev.notoptimal.net/search/label/NSTask for an overview of the problem, and a solution.
//I have not experienced the problem myself, so I can't comment.
+ (NSString*) executeShellCommandSynchronously:(NSString*)command
{
NSTask *task = [self taskForShellCommand:command];
//we pipe stdout and stderr into a file handle that we read to
NSPipe *outputPipe = [NSPipe pipe];
[task setStandardOutput: outputPipe];
[task setStandardError: outputPipe];
NSFileHandle *outputFileHandle = [outputPipe fileHandleForReading];
[task launch];
return [[[NSString alloc] initWithData:[outputFileHandle readDataToEndOfFile] encoding: NSUTF8StringEncoding] autorelease];
}
+ (oneway void) executeShellCommandAsynchronously:(NSString*)command
{
[[self taskForShellCommand:command] launch];
return;
}
@end