Swift进程输出与终端

时间:2019-07-02 18:56:05

标签: swift linux macos unix cocoa

我需要帮助来创建在Linux / Mac上运行的Swift程序,该程序将运行另一个进程。该过程从键盘读取一些数据,并将其输出显示在控制台/标签上。

我创建了一个简单的C程序,在输入名称时读取并显示它。然后确实在终端和Swift进程中运行了相同的代码。

终端显示消息“输入名称”,并等待输入。

但是在Swift Process的情况下,直到我将一些内容写到标准输入(管道)中之前,都不会出现此类消息。仅在将text + \ n写入标准输入后才能获得输出。

C代码

int main() {
    char name[25];
    char address[50];
    int pid = 0;
    printf("Enter name ");
    scanf("%s", name);
    printf("Name is %s\n", name);
    return 0; }

快捷代码

override func viewDidAppear() {
    do {
        try start("./My-Sample-C-Program")
    } catch {
    }
}

func start(_ command: String) throws {
    let process = Process()
    let outputHandler = Pipe()
    process.executableURL = URL(fileURLWithPath: command)
    process.standardOutput = outputHandler
    let inputHandler = Pipe()
    process.standardInput = inputHandler

    let handler = outputHandler.fileHandleForReading
    var dataObserver: NSObjectProtocol!
    dataObserver = NotificationCenter.default.addObserver(forName: .NSFileHandleDataAvailable, object: handler, queue: nil) {
        (notification) in
        let data = outputHandler.fileHandleForReading.availableData
        if data.count > 0 {
            if let result = String(data: data, encoding: .utf8) {
                print("\(result)")
            }
            else {
                print("Some other data!")
            }
            outputHandler.fileHandleForReading.waitForDataInBackgroundAndNotify()
        }
        else {
            NotificationCenter.default.removeObserver(dataObserver as Any)
        }
    }

    process.terminationHandler = {
        task in
        print("Terminated with status \(task.terminationStatus)")
    }

    handler.waitForDataInBackgroundAndNotify()
    try process.run()

    // If I comment the below line, no data will be displayed
    inputHandler.fileHandleForWriting.write("abab\n".data(using: .utf8)!)
}

端子输出

输入名称abc

名称是abc

Swift / Xcode输出

已终止,状态为0

输入名称,名称为abab

预期该进程与终端具有相同的行为,要求输入名称并按Enter进行显示。

如果我将以下几行添加到C程序中,它将按预期工作。有什么办法可以在Swift流程中做同样的事情?

setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);

0 个答案:

没有答案