Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running shell commands in a swift script

Tags:

shell

swift

zsh

I am looking for a solutuion to run shell commands in a Swift script.

Here is my code:

func shellEnv(_ command: String) -> String {
    let task = Process()
    let pipe = Pipe()
    
    task.standardOutput = pipe
    task.standardError = pipe
    task.arguments = ["-c", command]
    task.launchPath = "/bin/zsh"
    task.launch()
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: .utf8)!
    
    return output
}

It works with built-in commands but it cannot deal with commands like "brew", "node" and other commands that were installed manually.

So how can I solve it?

like image 906
Ivan1F Avatar asked Jan 19 '26 21:01

Ivan1F


1 Answers

You need to set the PATH environment variable for the task. This has been set in your terminal, which is why you are able to do brew and node and other cool things directly, without specifying their full path.

You can see what this is set to in your terminal by doing:

echo $PATH

and it will print something like (for me it has a bunch more things. This is only an excerpt):

/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

If you copy and paste the entire output of echo $PATH, and put it into the environment property of task, then you will be able to use the same commands in your swift script as in your terminal.

task.environment = ["PATH": "<paste the output here>"]

As Alexander said in the comments, another way is to add the l option. Here is a MCVE:

#!/usr/bin/swift

// main.swift
import AppKit

func shellEnv(_ command: String) -> String {
    let task = Process()
    let pipe = Pipe()
    
    task.standardOutput = pipe
    task.standardError = pipe
    task.arguments = ["-cl", command]
    task.launchPath = "/bin/zsh"
    task.launch()
    
    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = String(data: data, encoding: .utf8)!
    
    return output
}

print(shellEnv("brew list")) // assuming you have brew

To run, chmod +x main.swift then ./main.swift, and you will see all your homebrew packages listed.

like image 87
Sweeper Avatar answered Jan 21 '26 10:01

Sweeper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!