2017-01-18 4 views
3

Ich versuche, den Shell-Befehl in einem Swift-Skript zusammen zu ketten. Die tatsächlichen Befehle in Frage sind die Ausgabe von gource mit dem Eingang der ffmpeg geleitet, aber hier ist eine vereinfachte, erfundenes Beispiel von dem, was ich versuche zu tun:Verketten von Shell-Befehlen mit Pipe in einem Swift-Skript

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") 

Erwartete Ausgabe:

foo 
bar 
baz 

tatsächliche Ausgabe:

foo 
bar 
baz 
baz | uniq 

The | wird im Rahmen des letzten Arguments interpretiert. Wie kann ich Befehle zusammenführen, so dass Daten in einem Swift-Skript von einem zum nächsten fließen? Ich probierte verschiedene Kombinationen aus standardIn und standardOut und Pipe() zwischen zwei Process es, aber entweder mache ich es falsch, oder ich verbinde nicht die richtigen Stücke zusammen.

Antwort

7

Ich bekam eine Antwort mit Hilfe von 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

Vielen Dank! Ich habe viel zu lange damit verbracht, das auszuprobieren und nach Wegen zu suchen. –

0

Für andere, die in das gleiche Problem laufen kann, ist hier, was ich von Zevs Antwort abgeleitet mit dem Erstellen einer SHA1 HMAC-Hash zu passen:

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 
} 

Dies ist besonders nützlich, wenn einfache API-Aufrufe von Swift-Skripten durchgeführt werden, die einen Hash im HTTP-Header erfordern. Soweit ich fand, war dies die einzige Möglichkeit (da wir das Objective-C-CommonCrypto-Framework in Swift-Skripten nicht verwenden können)

Verwandte Themen