LoginSignup
3
1

More than 3 years have passed since last update.

Swift:Processでgrepする

Last updated at Posted at 2020-01-18

SwiftでCommand Line Toolを叩く時はProcessを使いますが,grepしたい時どうすればいいのかわかりづらかったので備忘録

func extractDefaultInternet() {
    // $ netstat -rnf inet | grep default
    let pipe1 = Pipe()
    let pipe2 = Pipe()

    let netstat = Process()
    netstat.launchPath = "/usr/bin/env"
    netstat.arguments = ["netstat", "-rnf", "inet"]
    netstat.standardOutput = pipe1

    let grep = Process()
    grep.launchPath = "/usr/bin/grep"
    grep.arguments = ["default"]
    grep.standardInput = pipe1
    grep.standardOutput = pipe2

    netstat.terminationHandler = { (_) in
        grep.launch()
    }
    netstat.launch()

    let data = pipe2.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: data, encoding: .utf8) else { return }
    Swift.print(output)
}

こんな感じでPipeを2個用意して,grepの方のstandardInputに一つ目のコマンドの出力結果のPipeを入れて,一つ目の実行結果の後にgrepを実行するようにterminationHandlerを登録してあげればOKです.

さらにgrepしたい時も同様の手順でOKです.

func en0() {
    // $ netstat -rnf inet | grep default | grep en0
    let pipe1 = Pipe()
    let pipe2 = Pipe()
    let pipe3 = Pipe()

    let netstat = Process()
    netstat.launchPath = "/usr/bin/env"
    netstat.arguments = ["netstat", "-rnf", "inet"]
    netstat.standardOutput = pipe1

    let grep = Process()
    grep.launchPath = "/usr/bin/grep"
    grep.arguments = ["default"]
    grep.standardInput = pipe1
    grep.standardOutput = pipe2

    let grep2 = Process()
    grep2.launchPath = "/usr/bin/grep"
    grep2.arguments = ["en0"]
    grep2.standardInput = pipe2
    grep2.standardOutput = pipe3

    grep.terminationHandler = { (_) in
        grep2.launch()
    }
    netstat.terminationHandler = { (_) in
        grep.launch()
    }
    netstat.launch()

    let data = pipe3.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: data, encoding: .utf8) else { return }
    Swift.print(output)
}

追記

いろいろやっていたらもっと強い方法を見つけてしまいました.

func runShell(_ args: String) {
    let process = Process()
    process.launchPath = "/bin/sh"
    process.arguments = ["-c", args]

    let pipe = Pipe()
    process.standardOutput = pipe
    process.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: data, encoding: .utf8) else { return }
    Swift.print(output)
}

runShell("ifconfig | grep broadcast")

シェルを文字列を引数にして叩けばなんでもありやないか...

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1