pomo_mondreganto
pomo_mondreganto

Reputation: 2074

Running terminal command in swift doesn't work

I'm trying to check if a brew command is available using command -v brew. Example output in terminal:

MacBook-Air-USER:~ USER$ command -v brew 
/usr/local/bin/brew

I'm using this code:

func runCommand(command cmd : String) -> Array<String> {
    var result : Array<String> = []

    let task = NSTask()
    task.launchPath = "/bin/bash"
    task.arguments = (["-c", cmd])

    let pipe = NSPipe()
    task.standardOutput = pipe
    let handle = pipe.fileHandleForReading
    handle.waitForDataInBackgroundAndNotify()

    let errPipe = NSPipe()
    task.standardError = errPipe
    let errHandle = errPipe.fileHandleForReading
    errHandle.waitForDataInBackgroundAndNotify()

    var startObserver : NSObjectProtocol!
    startObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSFileHandleDataAvailableNotification, object: nil, queue: nil) { notification -> Void in
        let data = handle.availableData
        if data.length > 0 {
            if let output = String(data: data, encoding: NSUTF8StringEncoding) {
                print("Output : \(output)")
                result.append(output)
            }
        }
        else {
            print("EOF on stdout")
            NSNotificationCenter.defaultCenter().removeObserver(startObserver)
        }
    }

    var endObserver : NSObjectProtocol!
    endObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification, object: nil, queue: nil) {
    notification -> Void in
        print("Task terminated with code \(task.terminationStatus)")
        NSNotificationCenter.defaultCenter().removeObserver(endObserver)
    }

    var errObserver : NSObjectProtocol!
    errObserver = NSNotificationCenter.defaultCenter().addObserverForName(NSTaskDidTerminateNotification, object: nil, queue: nil) {
    notification -> Void in
        let data = errHandle.availableData
        if (data.length > 0) {
            if let output = String(data: data, encoding: NSUTF8StringEncoding) {
                print("Error : \(output)")
                result.append(output)

                NSNotificationCenter.defaultCenter().removeObserver(errObserver)
            }
        }
    }

    task.launch()
    task.waitUntilExit()
    return result
}

And running it like this:

let arr = runCommand(command: "command -v brew")

And the array is always empty - I can't get any output. How to solve this problem?

UPD: The same happens if I try which brew command

UPD2: It works only with built-in commands, such as ls, but doesn't work with ones like brew or tor

Upvotes: 0

Views: 442

Answers (1)

emrys57
emrys57

Reputation: 6806

The $PATH of the instance of bash created to run the command may not be set. One way round this would be to specify an explicit path for the command:

runCommand(command: "command -v /usr/local/bin/brew")

Upvotes: 1

Related Questions