kun432's blog

技術ネタ、読書記録、など。2015年から人生をやり直し中です。

goで並列ping

とりあえずいろんなところを見て書いてみた。コマンドライン引数の使い方、ファイルの読み込み、並列処理、を一通り試せた感じ。

package main

import (
    "bufio"
    "fmt"
    "os"
    "os/exec"
    "sync"
)

func main() {
    // 引数処理
    args := os.Args
    fmt.Println(args)
    if len(args[1:]) != 1 {
        fmt.Println("Error! irregal arguments.")
        usage()
        os.Exit(1)
    }

    // リストファイルオープン
    r, err := os.Open(args[1])
    if err != nil {
        fmt.Println(err)
        usage()
        os.Exit(2)
    }
    defer r.Close()

    var iplist []string

    // リスト読み込み
    sc := bufio.NewScanner(r)
    for sc.Scan() {
        line := sc.Text()
        if line[:1] == "#" {
            continue
        }
        iplist = append(iplist, line)
    }

    // ping実行
    var wg sync.WaitGroup
    for _, ip := range iplist {
        wg.Add(1)
        go func(ip string) {
            defer wg.Done()
            worker(ip)
        }(ip)
    }
    wg.Wait()
}

func usage() {
    fmt.Println("[Usage] expingo IP_LIST_FILE")
}

func worker(ip string) {
    err := exec.Command("ping", "-c", "1", "-W", "1", ip).Run()

    if err != nil {
        fmt.Println(ip, " : NG")
    } else {
        fmt.Println(ip, " : OK")
    }
}
$ time go run parallel-ping.go dat/sample3.txt
・・・
192.168.4.13  : OK
192.168.4.1  : OK
192.168.4.2  : OK
192.168.4.14  : OK
192.168.4.15  : OK
192.168.4.10  : OK
192.168.4.18  : OK
192.168.4.19  : OK
192.168.4.12  : OK
192.168.1.1  : OK
192.168.4.3  : NG
192.168.4.22  : NG
・・・
real    0m3.332s
user    0m0.982s
sys     0m7.748s

700IPのリストで実際には10数台程度しかないけどすげえ速い。

pingを外部コマンドにしてるのがダサいので直したいと並列数の制御もできるようにしたい。