Go中的getpasswd功能?

Rog*_*erV 47 passwords stdin go getpasswd

情况:

我想从stdin控制台获取密码- 而不回显用户输入的内容.是否有类似getpasswdGo的功能?

我尝试了什么:

我尝试过使用syscall.Read,但它回应了所输入的内容.

gih*_*uka 81

以下是完成任务的最佳方法之一.首先得到terminal包裹go get golang.org/x/crypto/ssh

package main

import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "syscall"

    "golang.org/x/crypto/ssh/terminal"
)

func main() {
    username, password := credentials()
    fmt.Printf("Username: %s, Password: %s\n", username, password)
}

func credentials() (string, string) {
    reader := bufio.NewReader(os.Stdin)

    fmt.Print("Enter Username: ")
    username, _ := reader.ReadString('\n')

    fmt.Print("Enter Password: ")
    bytePassword, err := terminal.ReadPassword(int(syscall.Stdin))
    if err == nil {
        fmt.Println("\nPassword typed: " + string(bytePassword))
    }
    password := string(bytePassword)

    return strings.TrimSpace(username), strings.TrimSpace(password)
}
Run Code Online (Sandbox Code Playgroud)

http://play.golang.org/p/l-9IP1mrhA

  • 它没有工作,因为错误的假设0是Windows中的stdin处理程序(不是),你可以通过使用terminal.ReadPassword(int(syscall.Stdin))而不是0来使这个代码跨平台工作.很多,我认为最好的实施. (11认同)
  • 你可能不想从密码中修剪空间? (5认同)

Fat*_*lan 28

刚看到#go-nuts maillist中的邮件.有人写了一个很简单的go包来使用.你可以在这里找到它:https://github.com/howeyc/gopass

它是这样的:

package main

import "fmt"
import "github.com/howeyc/gopass"

func main() {
    fmt.Printf("Password: ")
    pass := gopass.GetPasswd()
    // Do something with pass
}
Run Code Online (Sandbox Code Playgroud)

  • 哦,还有[`terminal.ReadPassword`](https://godoc.org/golang.org/x/crypto/ssh/terminal/#ReadPassword). (9认同)
  • 注意,这个包使用Go作者的golang.org/x/crypto/ssh中的[`terminal.MakeRaw`](https://godoc.org/golang.org/x/crypto/ssh/terminal/#MakeRaw)/terminal`包.如果需要,可以直接使用. (7认同)

rus*_*tyx 10

从 Go ~v1.11 开始,有一个官方包golang.org/x/term取代了已弃用的crypto/ssh/terminal. 它具有除其他外的功能term.ReadPassword

用法示例:

package main
import (
    "fmt"
    "os"
    "syscall"
    "golang.org/x/term"
)
func main() {
    fmt.Print("Password: ")
    bytepw, err := term.ReadPassword(int(syscall.Stdin))
    if err != nil {
        os.Exit(1)
    }
    pass := string(bytepw)
    fmt.Printf("\nYou've entered: %q\n", pass)
}
Run Code Online (Sandbox Code Playgroud)


jsp*_*cal 7

您可以通过执行此操作stty -echo来关闭回声,然后stty echo在读取密码后将其重新打开


小智 7

我有一个类似的用例,下面的代码片段对我来说很好用。如果您仍然停留在这里,请随时尝试。

import (
    "fmt"
    "golang.org/x/crypto/ssh/terminal"

)

func main() {
    fmt.Printf("Now, please type in the password (mandatory): ")
    password, _ := terminal.ReadPassword(0)

    fmt.Printf("Password is : %s", password)
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要go get预先使用安装终端程序包。

  • 这在带有“句柄无效”的Windows上崩溃了。必须获取标准输入的实际fd:`terminal.ReadPassword(int(os.Stdin.Fd()))` (2认同)

Joe*_*off 5

这是我使用 Go1.6.2 开发的解决方案,您可能会发现它很有用。

它只使用下列标准包:bufiofmtosstringssyscall。更具体地说,它使用syscall.ForkExec()syscall.Wait4()调用 stty 来禁用/启用终端回声。

我已经在 Linux 和 BSD (Mac) 上对其进行了测试。它不会在 Windows 上工作。

// getPassword - Prompt for password. Use stty to disable echoing.
import ( "bufio"; "fmt"; "os"; "strings"; "syscall" )
func getPassword(prompt string) string {
    fmt.Print(prompt)

    // Common settings and variables for both stty calls.
    attrs := syscall.ProcAttr{
        Dir:   "",
        Env:   []string{},
        Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()},
        Sys:   nil}
    var ws syscall.WaitStatus

    // Disable echoing.
    pid, err := syscall.ForkExec(
        "/bin/stty",
        []string{"stty", "-echo"},
        &attrs)
    if err != nil {
        panic(err)
    }

    // Wait for the stty process to complete.
    _, err = syscall.Wait4(pid, &ws, 0, nil)
    if err != nil {
        panic(err)
    }

    // Echo is disabled, now grab the data.
    reader := bufio.NewReader(os.Stdin)
    text, err := reader.ReadString('\n')
    if err != nil {
        panic(err)
    }

    // Re-enable echo.
    pid, err = syscall.ForkExec(
        "/bin/stty",
        []string{"stty", "echo"},
        &attrs)
    if err != nil {
        panic(err)
    }

    // Wait for the stty process to complete.
    _, err = syscall.Wait4(pid, &ws, 0, nil)
    if err != nil {
        panic(err)
    }

    return strings.TrimSpace(text)
}
Run Code Online (Sandbox Code Playgroud)