2017-01-18 2 views
3

Я пытаюсь объединить команду оболочки в скрипте Swift. Фактические команды в которых идет речь, выход gource поступает на вход ffmpeg, но вот упрощена, надуманный пример того, что я пытаюсь сделать:Цепочные команды оболочки с трубой в скрипте Swift

let echo = Process() 

echo.launchPath = "/usr/bin/env" 
echo.arguments = ["echo", "foo\nbar\nbaz\nbaz", "|", "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") 

Ожидаемый результат:

foo 
bar 
baz 

Фактический выход:

foo 
bar 
baz 
baz | uniq 

The | интерпретируется как часть последнего аргумента. Как я могу объединить команды вместе, чтобы данные переходили от одного к другому, в сценарии Swift? Я пробовал различные комбинации присвоения standardIn и standardOut и используя Pipe() между двумя Process es, но либо я делаю это неправильно, либо я не соединяю нужные части вместе.

ответ

7

я получил ответ с помощью от zadr:

import Foundation 

let pipe = Pipe() 

let echo = Process() 
echo.launchPath = "/usr/bin/env" 
echo.arguments = ["echo", "foo\nbar\nbaz\nbaz"] 
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") 
+0

Спасибо! Я потратил слишком много времени, пытаясь разобраться в этом и попытаться найти пути вокруг него. –

0

Для других, которые могут быть запущены в одной и той же проблемой, вот что я полученный из ответа Зев, чтобы соответствовать с созданием хэш SHA1 HMAC:

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 
} 

Это особенно полезно при простых вызовах API из скриптов Swift, которые требуют хеша в заголовке HTTP. Насколько я понял, это был единственный способ, которым это было возможно (поскольку мы не можем использовать Objective-C CommonCrypto в сценариях Swift)

Смежные вопросы