我正在寻找一种方法来回答golang中的shell密码提示。
喜欢:
bussiere@kus:~/Workspace/rteest$ ./passwordtest.sh
Password :
我想在启动shell命令/脚本后在golang中使用我的令牌自动输入密码......
我已经制作了一些脚本,如果一切正常(在golang中),可以使用mfa获得一次性令牌。所以我需要输入临时令牌到linux密码提示符。
我知道有expect命令但是我想编译我的程序来嵌入它并且具有最小的依赖性。
谢谢和问候
编辑到@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)
}
它给了我这个:
2017/05/12 20:42:36 exit status 1
exit status 1
编辑bis:
cmdb := "git"
args := "https://bb@gitlab.com/bb/fzgs.git"
cmd := exec.Command(cmdb, "clone", args)
它要求输入密码:
&{39; https://bb@gitlab.com':
的密码答案 0 :(得分:4)
问题是你试图在Git问你之前发送密码 这样做。
Git要求输入密码的方式取决于是否设置了credential帮助程序。如果未设置凭证帮助程序,或者未返回密码,则会要求用户输入。
在大多数情况下(至少使用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()
另一种方法是制作凭证助手脚本,例如:
#!/bin/bash -
printf '%s\n' 'YOUR_PASSWORD'
并通过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()
答案 1 :(得分:2)
如果要求用户在其shell中输入密码,则可以使用golang 写入os.Stdin
的io.Writer
Properly passing data on stdin to a command and receiving data from stdout of that command in golang
os.Stdin
是由
os.File
NewFile(uintptr(syscall.Stdin), "/dev/stdin"
密码提示将从此文件中读取
您可以在问题中执行./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)
StdinPipe返回一个管道,该命令将在命令启动时连接到命令的标准输入。 Wait看到命令退出后,管道将自动关闭。呼叫者只需要调用关闭以强制管道更快关闭。例如,如果正在运行的命令在标准输入关闭之前不会退出,则调用者必须关闭管道。
此外,您的cmd
参数不应该与克隆和网址相结合,请改为使用
cmd := exec.Command(cmdb, "clone", url)