Search code examples
swiftmacosswift3swift2swift4

Swift mac app, run terminal command without knowing the path (so it looks in every path in $PATH)?


I'm trying to run terminal commands from my swift mac app, i want the users to enter any command like they would in the terminal without having to specify the real path. Is there a way to run a command and make it look in every path that's specified in the $PATH variable?

I can run commands when I specify the path but I need it to auto-find the binary from any path in the systems $PATH variable

    let path = "/usr/bin/killall"
    let arguments = ["Dock"]
    let task = Process.launchedProcess(launchPath: path, arguments: arguments)
    task.waitUntilExit()

In the future I would like to read .sh files and run every line in it, so for long scripts not all binaries will be in the default path.

Thanks!


Solution

  • You can execute the command via env:

    env utility argument ...
    

    Example:

    let path = "/usr/bin/env"
    let arguments = ["ls", "-l", "/"]
    let task = Process.launchedProcess(launchPath: path, arguments: arguments)
    task.waitUntilExit()
    

    env locates the given utility using the $PATH variable and then executes it with the given arguments. It has additional options to specify a different search path and additional environment variables.

    (This is not a feature of Swift but of macOS and many other operating systems.)

    When started from the Finder (double-click) the PATH may be different from the PATH in your shell environment. If necessary, you can add additional directories:

    var env = task.environment ?? [:]
    if let path = env["PATH"] {
        env["PATH"] = "/usr/local/bin:" + path
    } else {
        env["PATH"] = "/usr/local/bin"
    }
    task.environment = env
    

    execlp and friends also locate the executable using $PATH but offer only the "raw" C interface.