NSTask
是作为子进程运行另一个程序的类。你可以
捕获程序的输出、错误输出、退出状态等等。
扩展我的答案xcode 6 swift system() 命令,
这是一个同步运行命令的简单实用函数,
并返回输出、错误输出和退出代码(现已针对 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)
}
使用示例:
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)
}
或者,如果您只对输出感兴趣,而不是
错误消息或退出代码:
let output = runCommand("/usr/bin/git", args: "status").output
输出和错误输出作为字符串数组返回,其中一个
每行的字符串。
第一个参数runCommand()
必须是完整路径
可执行文件,例如"/usr/bin/git"
。您可以使用 shell 启动该程序(这就是system()
也一样):
let (output, error, status) = runCommand("/bin/sh", args: "-c", "git status")
优点是自动找到“git”可执行文件
通过默认搜索路径。缺点是你必须
如果参数包含空格或其他内容,请正确引用/转义参数
在 shell 中具有特殊含义的字符。
更新为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)
}