从 Golang 更改 linux 用户密码无效
Changing linux user password from Golang not working
我需要 go 例程中的一行代码来更改 linux 中的用户密码。
从命令行运行的命令:
echo 'pgc:password' | sudo chpasswd //"pgc" is the username and "password"
// is the password I'm changing it to.
但这在我的 Go 程序中不起作用。我试过用其他单行命令代替,例如:
drm file.txt, touch file.txt, 等等
这些都有效。
Go 程序在一个大项目中的一个包中,但我现在只是尝试直接从命令行 运行 它(不是用作函数,而是一个独立的 .go 文件)。
我的代码:
//I have tried changing back and forth between the package that changesystempassword.go is in
// and main, but that has no effect
package main //one-liners DON'T WORK if package is the package this go file is in
import (
"fmt"
"os/exec"
//"time"
)
func main() {
err := exec.Command("echo", "'pgc:password'", "|", "sudo", "chpasswd).Run()
//time.sleep(time.Second) - tried adding a sleep so it would have time?
if err != nil {
fmt.Println("Password change unsuccessful"
} else {
fmt.Println("Password change successful")
}
}
程序为运行(命令行中的./changesystempassword)时的结果是命令行显示“密码更改成功”。但猜猜怎么了。它没有改变。我在网上和 Stack Exchange 上找到了一些类似的示例,但我使用的是我在那里找到的解决方案,但它不起作用。
documentation 表示“使用给定的参数执行指定的程序”。甚至还有一个特定的段落:
Unlike the "system" library call from C and other languages, the os/exec package intentionally does not invoke the system shell and does not expand any glob patterns or handle other expansions, pipelines, or redirections typically done by shells.
因此问题中的代码执行 echo
,参数为 'pgc:password'
、|
、sudo
和 chpasswd
。这是成功的,因为 echo
可以完全打印这四个字符串。
解决方案是直接启动chpasswd
并写入其标准输入。这是一个最小的例子:
func main() {
cmd := exec.Command("chpasswd")
stdin, err := cmd.StdinPipe()
io.WriteString(stdin, "pgc:password")
}
我建议调整官方 example 中显示的代码,以获得安全代码 error-checking。
您也可以使用 sudo chpasswd
代替 chpasswd
。请记住,在这种情况下 sudo
将无法要求输入密码。一种解决方法是在适当的时候使用 NOPASSWD 配置 sudoers。
谢谢赫尔曼。我的误解有点微妙。我花了很长时间试图让你引导我工作的例子。直到一位同事建议我在参数传递给命令后抛出一个 \n,它才终于起作用了。
所以有效的代码(基本上是 Stdin 示例,稍作改动):
cmd := exec.Command("sudo", "chpasswd")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
go func() {
defer stdin.Close()
io.WriteString(stdin, "pgc:password\n")
}()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}
我需要 go 例程中的一行代码来更改 linux 中的用户密码。
从命令行运行的命令:
echo 'pgc:password' | sudo chpasswd //"pgc" is the username and "password"
// is the password I'm changing it to.
但这在我的 Go 程序中不起作用。我试过用其他单行命令代替,例如: drm file.txt, touch file.txt, 等等
这些都有效。
Go 程序在一个大项目中的一个包中,但我现在只是尝试直接从命令行 运行 它(不是用作函数,而是一个独立的 .go 文件)。
我的代码:
//I have tried changing back and forth between the package that changesystempassword.go is in
// and main, but that has no effect
package main //one-liners DON'T WORK if package is the package this go file is in
import (
"fmt"
"os/exec"
//"time"
)
func main() {
err := exec.Command("echo", "'pgc:password'", "|", "sudo", "chpasswd).Run()
//time.sleep(time.Second) - tried adding a sleep so it would have time?
if err != nil {
fmt.Println("Password change unsuccessful"
} else {
fmt.Println("Password change successful")
}
}
程序为运行(命令行中的./changesystempassword)时的结果是命令行显示“密码更改成功”。但猜猜怎么了。它没有改变。我在网上和 Stack Exchange 上找到了一些类似的示例,但我使用的是我在那里找到的解决方案,但它不起作用。
documentation 表示“使用给定的参数执行指定的程序”。甚至还有一个特定的段落:
Unlike the "system" library call from C and other languages, the os/exec package intentionally does not invoke the system shell and does not expand any glob patterns or handle other expansions, pipelines, or redirections typically done by shells.
因此问题中的代码执行 echo
,参数为 'pgc:password'
、|
、sudo
和 chpasswd
。这是成功的,因为 echo
可以完全打印这四个字符串。
解决方案是直接启动chpasswd
并写入其标准输入。这是一个最小的例子:
func main() {
cmd := exec.Command("chpasswd")
stdin, err := cmd.StdinPipe()
io.WriteString(stdin, "pgc:password")
}
我建议调整官方 example 中显示的代码,以获得安全代码 error-checking。
您也可以使用 sudo chpasswd
代替 chpasswd
。请记住,在这种情况下 sudo
将无法要求输入密码。一种解决方法是在适当的时候使用 NOPASSWD 配置 sudoers。
谢谢赫尔曼。我的误解有点微妙。我花了很长时间试图让你引导我工作的例子。直到一位同事建议我在参数传递给命令后抛出一个 \n,它才终于起作用了。
所以有效的代码(基本上是 Stdin 示例,稍作改动):
cmd := exec.Command("sudo", "chpasswd")
stdin, err := cmd.StdinPipe()
if err != nil {
log.Fatal(err)
}
go func() {
defer stdin.Close()
io.WriteString(stdin, "pgc:password\n")
}()
out, err := cmd.CombinedOutput()
if err != nil {
log.Fatal(err)
}