невозможно перенаправить вывод ruby-скрипта - PullRequest
0 голосов
/ 27 февраля 2019

Я пишу быстрое приложение для MacOSX. Это приложение использует Process для запуска большого количества скриптов, таких как shell 、 ruby ​​、 python.Когда приложение получит что-то из скрипта на выводе standerd, оно отобразится в приложении.пользователь делает что-то на основе того, что показывают в приложении.Затем приложение использует входные данные и отправляет их в сценарий.Процесс, описанный выше, может быть подан при запуске сценария.

Код, который я пишу, работает, но только для сценария оболочки.При запуске ruby ​​、 python , приложение не может получить вывод сценария.

файл сценария, подобный этому

# test.sh in my project
echo ~
read inputIn
echo "$inputIn"
read inputInOUt
mkDir "$inputInOUt"
# testruby.rb in my project
print "please input your name"
name=gets.chomp
puts "please input your age"
age=gets.chomp
# testpyton.pyt in my project

import sys

print "please input your name"
name=sys.stdin.readline()
print "please input your age"
age=sys.stdin.readline()
# work 
testInteract = EBInteract()
        testInteract?.excutScript("/Users/XXXXX/Library/Developer/Xcode/DerivedData/EasyBox-fmazpncoeyhnkgddokkilcbsebby/Build/Products/Debug/EasyBox.app/Contents/Resources/test.sh", "test_shell")

# can not work
//        testInteract = EBInteract()
//        testInteract?.excutScript("/Users/XXXXX/Library/Developer/Xcode/DerivedData/EasyBox-fmazpncoeyhnkgddokkilcbsebby/Build/Products/Debug/EasyBox.app/Contents/Resources/testruby.rb")

# can not work
//                testInteract = EBInteract()
//                testInteract?.excutScript("/Users/XXXXX/Library/Developer/Xcode/DerivedData/EasyBox-fmazpncoeyhnkgddokkilcbsebby/Build/Products/Debug/EasyBox.app/Contents/Resources/testpython.py")


import Foundation



/*
 * 该类负责与脚本交互
 */
class EBInteract {

    var times: Int = 1

    func excutScript(_ parameter: String...) -> Bool {
        guard parameter.count > 0 else {
            return false
        }

        let task = Process()
        let scriptFilePath = parameter[0]
        switch scriptFilePath {
        case _ where scriptFilePath.hasSuffix(".py"):
            task.launchPath = "/usr/local/bin/python"
        case _ where scriptFilePath.hasSuffix(".rb"):
                task.launchPath = "/Users/wangwenjun04/.rvm/rubies/ruby-2.4.1/bin/ruby"
//            task.launchPath = "/bin/bash"
        default:
                task.launchPath = "/bin/bash"
        }

        task.arguments = parameter

        let standardOutput = Pipe()
        task.standardOutput = standardOutput
        standardOutput.fileHandleForReading.waitForDataInBackgroundAndNotify()

        let standardInput = Pipe()
        task.standardInput = standardInput;
//        standardInput.fileHandleForWriting.readInBackgroundAndNotify()
//        standardInput.fileHandleForWriting.waitForDataInBackgroundAndNotify()


//        let fh = FileHandle(forWritingAtPath:"/Users/wangwenjun04/Library/Developer/Xcode/DerivedData/EasyBox-fmazpncoeyhnkgddokkilcbsebby/Build/Products/Debug/EasyBox.app/Contents/Resources/input.txt")
//        task.standardInput = fh
//        dup2(fh!.fileDescriptor, STDIN_FILENO)

        var dataObserver: NSObjectProtocol!
        dataObserver = NotificationCenter.default.addObserver(forName: Notification.Name.NSFileHandleDataAvailable,
                                                              object: standardOutput.fileHandleForReading, queue: OperationQueue.main, using: {notification in
                    if let output = notification.object as? FileHandle {
                        let data = output.availableData

                        guard data.count > 0 else {
                            NotificationCenter.default.removeObserver(dataObserver)
                            return
                        }



                        let outPutInfo: String? = String(data: data, encoding: String.Encoding.utf8)

                        print("output info is \(outPutInfo ?? "nothing")")


                        if self.times == 1 {
                            if let input = task.standardInput as? Pipe {

                                var info1 = "wwj-wwj\n"
                                input.fileHandleForWriting.write(info1.data(using: String.Encoding.utf8)!)
//                                input.synchronizeFile()
                            }

                            self.times += 1
                        }
                        else {
                            if let input = task.standardInput as? Pipe {
                                var info1 = "wwj-18\n"
                                input.fileHandleForWriting.write(info1.data(using: String.Encoding.utf8)!)
//                                input.synchronizeFile()
                            }
                        }

                        standardOutput.fileHandleForReading.waitForDataInBackgroundAndNotify()
                    }
            })



        task.launch()
//        task.waitUntilExit()

        return true
    }
}

...