NSTask is a class for running another program as a subprocess. You can capture program output, error output, exit status, and more.
Expanding my response to the xcode 6 swift system () command , here is a simple utility function to run the command synchronously, and return the output, error output and exit code (now updated for Swift 2):
func runCommand(cmd : String, args : String...) -> (output: [String], error: [String], exitCode: Int32) { var output : [String] = [] var error : [String] = [] let task = NSTask() task.launchPath = cmd task.arguments = args let outpipe = NSPipe() task.standardOutput = outpipe let errpipe = NSPipe() task.standardError = errpipe task.launch() let outdata = outpipe.fileHandleForReading.readDataToEndOfFile() if var string = String.fromCString(UnsafePointer(outdata.bytes)) { string = string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet()) output = string.componentsSeparatedByString("\n") } let errdata = errpipe.fileHandleForReading.readDataToEndOfFile() if var string = String.fromCString(UnsafePointer(errdata.bytes)) { string = string.stringByTrimmingCharactersInSet(NSCharacterSet.newlineCharacterSet()) error = string.componentsSeparatedByString("\n") } task.waitUntilExit() let status = task.terminationStatus return (output, error, status) }
Sample Usage:
let (output, error, status) = runCommand("/usr/bin/git", args: "status") print("program exited with status \(status)") if output.count > 0 { print("program output:") print(output) } if error.count > 0 { print("error output:") print(error) }
Or, if you are only interested in output, but not in error messages or exit code:
let output = runCommand("/usr/bin/git", args: "status").output
The output and output of the error is returned as an array of strings, one row for each row.
The first argument to runCommand() should be the full path to the executable, for example, "/usr/bin/git" . You can run the program using the shell (which is what system() does):
let (output, error, status) = runCommand("/bin/sh", args: "-c", "git status")
The advantage is that the git executable is automatically found through the default search path. The downside is that you must quote / escape arguments correctly if they contain spaces or other characters that have special meaning in the shell.
Update for Swift 3:
func runCommand(cmd : String, args : String...) -> (output: [String], error: [String], exitCode: Int32) { var output : [String] = [] var error : [String] = [] let task = Process() task.launchPath = cmd task.arguments = args let outpipe = Pipe() task.standardOutput = outpipe let errpipe = Pipe() task.standardError = errpipe task.launch() let outdata = outpipe.fileHandleForReading.readDataToEndOfFile() if var string = String(data: outdata, encoding: .utf8) { string = string.trimmingCharacters(in: .newlines) output = string.components(separatedBy: "\n") } let errdata = errpipe.fileHandleForReading.readDataToEndOfFile() if var string = String(data: errdata, encoding: .utf8) { string = string.trimmingCharacters(in: .newlines) error = string.components(separatedBy: "\n") } task.waitUntilExit() let status = task.terminationStatus return (output, error, status) }