V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
The Go Programming Language
http://golang.org/
Go Playground
Go Projects
Revel Web Framework
wuzhewuyou
V2EX  ›  Go 编程语言

go exec 控制台直接运行执行命令正常,改成服务后不运行

  •  
  •   wuzhewuyou · 2023-04-26 17:12:15 +08:00 · 1827 次点击
    这是一个创建于 577 天前的主题,其中的信息可能已经有所发展或是发生改变。

    centos7 检查目标 ip 是否在线的代码,直接运行是正常的,但是改成 service 运行, [Install] WantedBy=multi-user.target

    正常运行时,目标 ip 不在线是打印 exit status 1

    现在不管在线否都是直接打印出 exit status 2

    
    func NetWorkStatus(host string) bool {
    	cmd := exec.Command("ping", host, "-c", "4", "-w", "5")
    	fmt.Println("NetWorkStatus Start:", time.Now().Unix())
    	err := cmd.Run()
    	fmt.Println("NetWorkStatus End  :", time.Now().Unix())
    	if err != nil {
    		fmt.Println(err.Error())
    		return false
    	} else {
    		fmt.Println("Net Status , OK")
    	}
    	return true
    }
    

    看到部分文章提示用到 ICMP ,这需要以管理员身份运行。

    service multi-user.target 这还不是管理员身份么?

    18 条回复    2023-04-27 18:20:30 +08:00
    elechi
        1
    elechi  
       2023-04-26 17:34:11 +08:00
    是不是 path 环境变量问题,ping 命令找不到
    ysc3839
        2
    ysc3839  
       2023-04-26 17:36:15 +08:00 via Android
    Golang 连个 ping 的包都没吗?一定要调用外部程序?
    seers
        3
    seers  
       2023-04-26 17:37:49 +08:00 via Android
    自己实现一个吧,也不难
    RedisMasterNode
        4
    RedisMasterNode  
       2023-04-26 17:42:06 +08:00
    @ysc3839 是有的 而且还有 > 1k 的 star....
    sadfQED2
        5
    sadfQED2  
       2023-04-26 17:59:33 +08:00 via Android
    目测 99%概率是因为环境变量的问题。

    另外同好奇为啥不用现成的包
    wuzhewuyou
        6
    wuzhewuyou  
    OP
       2023-04-26 18:17:45 +08:00 via Android
    @elechi go run main.go 是正常的,即使程序路径改成 /usr/bin/ping ,症状也一样
    zhangsanfeng2012
        7
    zhangsanfeng2012  
       2023-04-26 19:34:02 +08:00
    域名没办法解析吧
    mogging
        8
    mogging  
       2023-04-26 21:24:21 +08:00 via Android
    我遇到过一次类似的错误,systemd 服务配置加个 privilege 参数就可以了,不妨试试看
    nulIptr
        9
    nulIptr  
       2023-04-26 21:31:19 +08:00
    都用 go 了为啥不直接发 tcp 或者 http 。。。
    0o0O0o0O0o
        10
    0o0O0o0O0o  
       2023-04-26 21:40:07 +08:00 via iPhone
    可以用 systemd-run 来调试排查,ICMP 需要 cap_net_raw ,systemd unit 的编写可以多问问 chatgpt ,它很擅长
    lqhx
        11
    lqhx  
       2023-04-26 23:49:34 +08:00
    err.Error 打印出来是啥?
    感觉和 service 运行时的环境有关
    dode
        12
    dode  
       2023-04-27 02:33:43 +08:00 via Android
    还是跑 docker ,自启动方便啊
    tinyint00
        13
    tinyint00  
       2023-04-27 08:06:37 +08:00
    这个类似的做法,你指定用户试试 user, err := user.Lookup("you user name")

    ```go
    c.clientCmd = exec.Command(name, args...)
    // c.clientCmd.Stdin = os.Stdin
    // c.clientCmd.Stdout = os.Stdout
    // c.clientCmd.Stderr = os.Stderr
    // c.clientCmd = exec.Command("sh")
    fmt.Println(c.clientCmd.String())
    var err error
    user, err := user.Lookup("you user name")
    if err != nil {
    fmt.Println(err, "invalid user", name)
    return
    }

    // var ids_s, _ = user.GroupIds()
    // ids := make([]uint32, len(ids_s), len(ids_s))

    // for k, _ := range ids_s {
    // s, _ := strconv.Atoi(ids_s[k])
    // ids[k] = uint32(s)
    // }

    // 获取用户 id
    uid, err := strconv.ParseUint(user.Uid, 10, 32)
    if err != nil {
    fmt.Println(err)
    }

    // 获取用户组 id
    gid, err := strconv.ParseUint(user.Gid, 10, 32)
    if err != nil {
    fmt.Println(err)
    }
    c.clientCmd.SysProcAttr = &syscall.SysProcAttr{
    // Cloneflags: syscall.CLONE_NEWUTS |
    // syscall.CLONE_NEWIPC |
    // syscall.CLONE_NEWPID |
    // syscall.CLONE_NEWNS |
    // syscall.CLONE_NEWUSER |
    // syscall.CLONE_NEWNET,

    Pdeathsig: syscall.SIGKILL, // linux 下退出后杀死子孙进程 或者设置 {Setpgid: false}
    }

    //设置进程执行用户
    c.clientCmd.SysProcAttr.Credential = &syscall.Credential{
    Uid: uint32(uid),
    Gid: uint32(gid),
    }

    // c.read()

    time.Sleep(time.Second * 2)
    fmt.Println("xxxx")
    err = c.clientCmd.Start()

    if err != nil {
    fmt.Printf("error start: -> %s ", err.Error())
    return
    }

    err = c.clientCmd.Wait()
    if err != nil {
    fmt.Printf("error wait: -> %s ", err.Error())
    return
    }

    ```
    learningman
        14
    learningman  
       2023-04-27 09:01:29 +08:00 via Android
    为啥不用 x net 里的 icmp ,非要调命令行
    lysS
        15
    lysS  
       2023-04-27 16:20:42 +08:00
    少用这种 cmd ,根本没有鲁棒性,而且不好处理。

    https://github.com/prometheus-community/pro-bing
    wuzhewuyou
        16
    wuzhewuyou  
    OP
       2023-04-27 16:33:26 +08:00
    用了 pro-bing 库

    centos7 下面 root 用户和服务启动

    错误提示都是 socket: permission denied
    wuzhewuyou
        17
    wuzhewuyou  
    OP
       2023-04-27 16:48:42 +08:00
    关了 selinux 也不行

    奇了怪 ///
    feelinglucky
        18
    feelinglucky  
       2023-04-27 18:20:30 +08:00
    centos ? selinux 没有关?
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2852 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 34ms · UTC 13:53 · PVG 21:53 · LAX 05:53 · JFK 08:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.