本文演示用Swift作为脚本使用,并简单封装调用系统命令的功能。
1、hello world
创建文件hello.swift
#!/usr/bin/env xcrun swift
print("hello world")
添加可执行属性
chmod +x hello.swift
运行脚本
./hello.swift
咦,好慢呀,需要两秒钟还多。别急!第一次运行需要编译,第二次运行就很快了。
2、调用系统工具
比如我用要调用date "+%y-%m-%d %H:%M:%S"
显示日期,可以这么做
#!/usr/bin/env xcrun swift
import Foundation
func exec(_ cmd: String, _ args: [String]? = nil) -> Int {
let task = Process()
task.launchPath = cmd
if args != nil {
task.arguments = args!
}
task.launch()
task.waitUntilExit()
return Int(task.terminationStatus)
}
exec("/bin/date", ["+%y-%m-%d %H:%M:%S"])
能正确的输出时间18-04-05 07:01:54
我们这个exec函数不太方便,调用命令的时候要输入完整路径,怎样简短一些呢?
我们再写一个小函数envExec
,就可以方便一点了
func envExec(_ args: [String]? = nil) -> Int {
return exec("/usr/bin/env", args)
}
现在可以这样用:
envExec(["date", "+%y-%m-%d %H:%M:%S"])
还需要加上捕获系统输出和错误输出功能,代码如下:
#!/usr/bin/env xcrun swift
import Foundation
func exec(_ cmd: String, _ args: [String]? = nil) -> (String, String, Int) {
let task = Process()
task.launchPath = cmd
if args != nil {
task.arguments = args!
}
let outpipe = Pipe()
task.standardOutput = outpipe
let errpipe = Pipe()
task.standardError = errpipe
task.launch()
let outdata = outpipe.fileHandleForReading.availableData
let outputString = String(data: outdata, encoding: String.Encoding.utf8) ?? ""
let errdata = errpipe.fileHandleForReading.availableData
let errString = String(data: errdata, encoding: String.Encoding.utf8) ?? ""
task.waitUntilExit()
return (outputString, errString, Int(task.terminationStatus))
}
func envExec(_ args: [String]? = nil) -> (String, String, Int) {
return exec("/usr/bin/env", args)
}
let status: Int
let output: String
let err: String
(output, err, status) = envExec(["date", "+%y-%m-%d %H:%M:%S"])
if status == 0 {
print(output, terminator: "")
} else {
print(err, terminator: "")
}
试一下,能正常工作。
exec和envExec使用示例:
exec("/bin/ls", ["hello.swift"])
envExec(["ls", "hello.swift"])
返回值有三个,分别是标准输出、错误输出、返回值。
如果返回值为0表示执行成功。
3、总结
上面调用系统命令的方式看起来不够简洁,不如Shell方便,但是你的脚本业务逻辑比较多的情况下Swift的表达能力就比Shell强很多啦!什么?人生苦短,你用Python。好吧!
网友评论