Chaining shell commands with pipe in a Swift script
我正在尝试在 Swift 脚本中将 shell 命令链接在一起。有问题的实际命令是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | let echo = Process() echo.launchPath ="/usr/bin/env" echo.arguments = ["echo","foo\ bar\ baz\ baz","|","uniq"] let pipe = Pipe() echo.standardOutput = pipe echo.launch() echo.waitUntilExit() // Get the data let data = pipe.fileHandleForReading.readDataToEndOfFile() let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) print(output ??"no output") |
预期输出:
1 2 3 | foo bar baz |
实际输出:
1 2 3 4 | foo bar baz baz | uniq |
我在 zadr 的帮助下得到了答案:
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 | import Foundation let pipe = Pipe() let echo = Process() echo.launchPath ="/usr/bin/env" echo.arguments = ["echo","foo\ bar\ baz\ baz"] echo.standardOutput = pipe let uniq = Process() uniq.launchPath ="/usr/bin/env" uniq.arguments = ["uniq"] uniq.standardInput = pipe let out = Pipe() uniq.standardOutput = out echo.launch() uniq.launch() uniq.waitUntilExit() let data = out.fileHandleForReading.readDataToEndOfFile() let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue) print(output ??"no output") |
对于可能遇到相同问题的其他人,这是我从 Zev 的回答中得出的适合创建 SHA1 HMAC 哈希的内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | func getHMAC(forValue value: String, key: String) -> String { let pipe = Pipe() let echo = Process() echo.launchPath ="/usr/bin/env" echo.arguments = ["echo","-n", value] echo.standardOutput = pipe let task = Process() task.launchPath ="/usr/bin/env" task.arguments = ["openssl","sha1","-hmac", key] task.standardInput = pipe let output = Pipe() task.standardOutput = output echo.launch() task.launch() task.waitUntilExit() let data = output.fileHandleForReading.readDataToEndOfFile() return NSString(data: data, encoding: String.Encoding.utf8.rawValue) as! String } |
这在从需要 HTTP 标头中的哈希值的 Swift 脚本中进行简单的 API 调用时特别有用。据我所知,这是唯一可行的方法(因为我们无法在 Swift 脚本中使用 Objective-C CommonCrypto 框架)
你应该看看这个。这是通过链接进行管道传输的简单方法的示例。 https://gist.github.com/eahrold/b5c5fd455225a8726e1cc31708e139db
所以你可以像
1 2 3 4 5 6 7 8 9 | let ls = Process("/bin/ls", ["-al"]) let grep = Process("/usr/bin/grep", ["com"]) let cut = Process("/usr/bin/awk", ["{print $3}"]) ls.pipe(grep).pipe(cut).complete { message, status in print("Your results: \\(message)") } ls.launch() |