我正在寻找一种方法来回答golang中的shell密码提示.
喜欢 :
bussiere@kus:~/Workspace/rteest$ ./passwordtest.sh
Password :
Run Code Online (Sandbox Code Playgroud)
在启动shell命令/脚本后,我想在golang中使用我的令牌自动输入密码...
我已经制作了一些脚本,如果一切正常(在golang中),可以使用mfa获得一次性令牌.所以我需要输入tempory标记到linux密码提示符.
我知道有期望命令,但我想编译我的程序嵌入它并具有最小的依赖性.
感谢致敬
编辑到@nevermore我试过这个(但它不起作用):https://play.golang.org/p/Ffm3q5h636
package main
import (
"os/exec"
"fmt"
"log"
"io"
)
func main() {
cmdb := "git"
args := "clone https://bb@gitlab.com/bb/fzgs.git"
cmd := exec.Command(cmdb, args)
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
go func() {
defer stdin.Close()
io.WriteString(stdin, "QSRDFGHJfZERTYU")
}()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", out)
}
Run Code Online (Sandbox Code Playgroud)
它给了我这个:
2017/05/12 20:42:36 exit status 1
exit status 1
Run Code Online (Sandbox Code Playgroud)
编辑之二:
cmdb := "git"
args := "https://bb@gitlab.com/bb/fzgs.git"
cmd := exec.Command(cmdb, "clone", args)
Run Code Online (Sandbox Code Playgroud)
它要求输入密码:
" https://bb@gitlab.com "的密码:
问题是您试图在 Git 要求您发送密码之前发送密码。
Git 询问密码的方式取决于是否设置了凭证助手。如果未设置凭据帮助程序,或未返回密码,则会要求用户输入。
在大多数情况下(至少对于 Github 和 Bitbucket),Git 服务器接受通过 HTTPS URI 传递的凭据,例如https://user:password@domain.com/repo.git.
cmd := exec.Command("git", "clone", "https://bb:PASSWORD@gitlab.com/bb/fzgs.git")
env := os.Environ()
env = append(env, "GIT_ASKPASS=")
cmd.Env = env
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
Run Code Online (Sandbox Code Playgroud)
另一种方法是制作凭证帮助程序脚本,例如:
#!/bin/bash -
printf '%s\n' 'YOUR_PASSWORD'
Run Code Online (Sandbox Code Playgroud)
并通过它传递GIT_ASKPASS:
cmd := exec.Command("git", "clone", "https://bb@gitlab.com/bb/fzgs.git")
env := os.Environ()
env = append(env, "GIT_ASKPASS=/path/to/fzgs-askpass.sh")
cmd.Env = env
var out bytes.Buffer
cmd.Stdout = &out
err := cmd.Run()
Run Code Online (Sandbox Code Playgroud)
如果用户在 shell 中被要求输入密码,您可以使用 golang 写入io.Writer,即os.Stdin
在 golang 中正确地将 stdin 上的数据传递给命令并从该命令的 stdout 接收数据
os.Stdin是一个os.File创建者
NewFile(uintptr(syscall.Stdin), "/dev/stdin")
Run Code Online (Sandbox Code Playgroud)
密码提示将从该文件中读取
您可以./passwordtest.sh按照您的问题执行,然后将密码写入os.Stdin,bash 脚本应该接受 golang 写入的字节作为密码。
或者实际上是exec类型包中的一个方法Cmd。
cmd.StdinPip()cmd.CombinedOutput()Cmd 表示正在准备或运行的外部命令。
https://golang.org/pkg/os/exec/#Cmd.StdinPipe
cmd := exec.Command("cat")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
go func() {
defer stdin.Close()
io.WriteString(stdin, "values written to stdin are passed to cmd's standard input")
}()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", out)
Run Code Online (Sandbox Code Playgroud)
StdinPipe 返回一个管道,该管道将在命令启动时连接到命令的标准输入。Wait 看到命令退出后,管道将自动关闭。调用者只需调用 Close 即可强制管道更快关闭。例如,如果正在运行的命令在标准输入关闭之前不会退出,则调用者必须关闭管道。
另外,你的cmd参数不应该结合克隆和网址,而是尝试
cmd := exec.Command(cmdb, "clone", url)
Run Code Online (Sandbox Code Playgroud)