Skip to content

Instantly share code, notes, and snippets.

@adam-zethraeus
Forked from andreacipriani/Bash.swift
Created December 25, 2023 09:57
Show Gist options
  • Save adam-zethraeus/f2a83c900367a37aa8c1430df1025982 to your computer and use it in GitHub Desktop.
Save adam-zethraeus/f2a83c900367a37aa8c1430df1025982 to your computer and use it in GitHub Desktop.
Execute shell/bash commands from Swift
import UIKit
protocol CommandExecuting {
func run(commandName: String, arguments: [String]) throws -> String
}
enum BashError: Error {
case commandNotFound(name: String)
}
struct Bash: CommandExecuting {
func run(commandName: String, arguments: [String] = []) throws -> String {
return try run(resolve(commandName), with: arguments)
}
private func resolve(_ command: String) throws -> String {
guard var bashCommand = try? run("/bin/bash" , with: ["-l", "-c", "which \(command)"]) else {
throw BashError.commandNotFound(name: command)
}
bashCommand = bashCommand.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
return bashCommand
}
private func run(_ command: String, with arguments: [String] = []) throws -> String {
let process = Process()
process.launchPath = command
process.arguments = arguments
let outputPipe = Pipe()
process.standardOutput = outputPipe
process.launch()
let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
let output = String(decoding: outputData, as: UTF8.self)
return output
}
}
let bash: CommandExecuting = Bash()
if let lsOutput = try? bash.run(commandName: "ls", arguments: []) { print(lsOutput) }
if let lsWithArgumentsOutput = try? bash.run(commandName: "ls", arguments: ["-la"]) { print(lsWithArgumentsOutput) }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment