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

229 天前
 zzzkkk

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

搞了好久了 没成功

原始命令为 ssh -i '/f/Download/new aws.pem' ec2-user@xxx.xxx.xxx.xxx 'wc -l /home/e.csv'

package main

import (
        "fmt"
        "os/exec"
)

func main() {
    args := []string{"-i '/f/Download/new aws.pem' ec2-user@xxx.xxx.xxx.xxx","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)
}
1422 次点击
所在节点    Go 编程语言
13 条回复
ysc3839
229 天前
Unix 的进程参数是字符串数组,在 shell 中一个字符串命令会经过解析,得到字符串数组后传递。解析逻辑大致是按空格分割,同时处理引号包裹、转义等等。
你这个例子,args 应该是:
-i
/f/Download/new aws.pem
ec2-user@xxx.xxx.xxx.xxx
wc -l /home/e.csv
mainjzb
229 天前
args := []string{"-i", "/f/Download/new aws.pem", "ec2-user@xxx.xxx.xxx.xxx", "wc -l /home/e.csv"}
ysc3839
229 天前
另外,如果只是想并行执行,还不如直接用 GNU parallel
fdwjtz
229 天前
看起来是 wc 那句直接被当成 ssh 的参数送进去了,根本没解析
dayeye2006199
229 天前
ansible 了解一下朋友
xxxeeeex
229 天前
polythene
229 天前
为啥不直接用 shell ?

cat ec2_ip_list | xargs -i ssh -i '/f/Download/new aws.pem' ec2-user@{} wc -l /home/e.csv
zzzkkk
229 天前
@polythene
接下来还要做复杂一点的动作
你这样做顺序执行 没有 goroutine 快
polythene
229 天前
@zzzkkk xargs -P 100 ? 本身用 go 转了一层再去调 shell 的方式,看起来就很别扭
nuk
229 天前
建议用 ssh 库,我做过一样的东西,直接调用命令的话,ssh 进程多了会完全卡死
rekulas
228 天前
你这原始命令并不是一个单一命令啊, 直接当成参数肯定不行的,得用 pipe 管道组合下
偷懒也可以直接命令全放到 shell 文件里执行 shell
LindsayZhou
228 天前
1 楼的解释是对的。

这种工作不适合用编译型语言跑,我的习惯是编译型语言不应该有这种不可控的依赖(外部的 ssh )。
我自己喜欢用 python 的 asyncssh 写脚本跑。
在用 python 的 asyncio 前,是用线程池跑 fabric (不喜欢 ansible )。
我同事喜欢用 https://github.com/ParallelSSH/parallel-ssh
tkoi
195 天前
你需要使用 golang.org/x/crypto/ssh 库,这个可以实现你需要的功能,建议配合 github.com/spf13/viper 库来加载配置文件,配置文件可以使用 toml 格式,将 ssh 认证信息及需要被执行的命令,灵活的传递。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/977898

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX