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

go 调用外部 ssh 命令 自动执行命令

  •  
  •   zzzkkk · 2023-09-28 13:30:21 +08:00 · 1619 次点击
    这是一个创建于 421 天前的主题,其中的信息可能已经有所发展或是发生改变。

    很多太 ec2 机器 想通过 go 实现快速执行命令

    搞了好久了 没成功

    原始命令为 ssh -i '/f/Download/new aws.pem' [email protected] 'wc -l /home/e.csv'

    package main
    
    import (
            "fmt"
            "os/exec"
    )
    
    func main() {
        args := []string{"-i '/f/Download/new aws.pem' [email protected]","wc -l /home/e.csv"}
        cmd := exec.Command("ssh",args...)
        ret,err := cmd.Output()
        if err != nil {
            fmt.Printf("\nerr:%v\n", err)
        }
        fmt.Printf("%v\n",ret)
    }
    
    13 条回复    2023-11-01 17:46:56 +08:00
    ysc3839
        1
    ysc3839  
       2023-09-28 13:36:09 +08:00 via Android
    Unix 的进程参数是字符串数组,在 shell 中一个字符串命令会经过解析,得到字符串数组后传递。解析逻辑大致是按空格分割,同时处理引号包裹、转义等等。
    你这个例子,args 应该是:
    -i
    /f/Download/new aws.pem
    [email protected]
    wc -l /home/e.csv
    mainjzb
        2
    mainjzb  
       2023-09-28 13:37:00 +08:00
    args := []string{"-i", "/f/Download/new aws.pem", "[email protected]", "wc -l /home/e.csv"}
    ysc3839
        3
    ysc3839  
       2023-09-28 13:37:14 +08:00 via Android
    另外,如果只是想并行执行,还不如直接用 GNU parallel
    fdwjtz
        4
    fdwjtz  
       2023-09-28 13:39:08 +08:00 via Android
    看起来是 wc 那句直接被当成 ssh 的参数送进去了,根本没解析
    dayeye2006199
        5
    dayeye2006199  
       2023-09-28 13:43:42 +08:00
    ansible 了解一下朋友
    xxxeeeex
        6
    xxxeeeex  
       2023-09-28 13:46:06 +08:00
    polythene
        7
    polythene  
       2023-09-28 15:29:56 +08:00
    为啥不直接用 shell ?

    cat ec2_ip_list | xargs -i ssh -i '/f/Download/new aws.pem' ec2-user@{} wc -l /home/e.csv
    zzzkkk
        8
    zzzkkk  
    OP
       2023-09-28 15:34:02 +08:00 via Android
    @polythene
    接下来还要做复杂一点的动作
    你这样做顺序执行 没有 goroutine 快
    polythene
        9
    polythene  
       2023-09-28 17:51:27 +08:00
    @zzzkkk xargs -P 100 ? 本身用 go 转了一层再去调 shell 的方式,看起来就很别扭
    nuk
        10
    nuk  
       2023-09-28 18:17:42 +08:00
    建议用 ssh 库,我做过一样的东西,直接调用命令的话,ssh 进程多了会完全卡死
    rekulas
        11
    rekulas  
       2023-09-28 22:47:50 +08:00
    你这原始命令并不是一个单一命令啊, 直接当成参数肯定不行的,得用 pipe 管道组合下
    偷懒也可以直接命令全放到 shell 文件里执行 shell
    LindsayZhou
        12
    LindsayZhou  
       2023-09-29 16:56:21 +08:00
    1 楼的解释是对的。

    这种工作不适合用编译型语言跑,我的习惯是编译型语言不应该有这种不可控的依赖(外部的 ssh )。
    我自己喜欢用 python 的 asyncssh 写脚本跑。
    在用 python 的 asyncio 前,是用线程池跑 fabric (不喜欢 ansible )。
    我同事喜欢用 https://github.com/ParallelSSH/parallel-ssh
    tkoi
        13
    tkoi  
       2023-11-01 17:46:56 +08:00
    你需要使用 golang.org/x/crypto/ssh 库,这个可以实现你需要的功能,建议配合 github.com/spf13/viper 库来加载配置文件,配置文件可以使用 toml 格式,将 ssh 认证信息及需要被执行的命令,灵活的传递。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2647 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 15:11 · PVG 23:11 · LAX 07:11 · JFK 10:11
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.