【问题标题】:Running external commands through os/exec under another user在另一个用户下通过 os/exec 运行外部命令
【发布时间】:2014-03-09 11:32:33
【问题描述】:

使用os/exec 包,我想代表另一个用户在*nix OS 上运行一个外部命令(当然go 进程在另一个具有su 权限的用户的root 用户下运行)

我想避免使用“su”或“bash”命令,并完全使用 go。

我使用syscall.Setuid 做了一个方法,但这会将用户更改为主项目,我只需要将用户更改为外部子进程:

func (self *Command) LoseTo(username string) {
   u, err := user.Lookup(username)
   if err != nil {
      fmt.Printf("%v", err)
   }

   uid, err := strconv.Atoi(u.Uid)
   if err := syscall.Setuid(uid); err != nil {
      fmt.Printf("%v", err)
   }
}

【问题讨论】:

    标签: go exec sudo


    【解决方案1】:

    如果有人正在寻找工作代码 sn-p:

    u, erru := user.Lookup(LocalUserName)
    if erru != nil {
        fmt.Println( erru, " for ",LocalUserName)
    }
    uid, err = strconv.ParseInt(u.Uid, 10, 32)
    gid, err = strconv.ParseInt(u.Gid, 10, 32)
    
    cmd := exec.Command("/bin/uname", "-a")
    cmd.Stdout = &out
    cmd.Stderr = &stderr
    cmd.SysProcAttr = &syscall.SysProcAttr{}
    cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uint32(uid), Gid: uint32(gid)}
    err = cmd.Run()
    

    【讨论】:

      【解决方案2】:

      您可以将 syscall.Credential 结构添加到 Cmd.SysProcAttr

      cmd := exec.Command(command, args...)
      cmd.SysProcAttr = &syscall.SysProcAttr{}
      cmd.SysProcAttr.Credential = &syscall.Credential{Uid: uid, Gid: gid}
      

      【讨论】:

      • 很好的答案,但只是想注意系统调用包在操作系统之间是不一样的。来自documentation,“syscall 的主要用途是在为系统提供更便携接口的其他包中,例如“os”、“time”和“net”。如果可以,请使用这些包而不是这个包”。这是一个很好的解决方案,但需要额外的代码才能使其独立于平台。
      • @RickSmith:当然,但问题专门针对“*nix OS”
      • @JimB 我不确定syscall 对未来读者的影响有多明显。我想我只是因为没有意识到syscall 的本质而被咬了。答案使用并点赞!
      • 这在 Mac OS X 上对我不起作用,有什么具体的事情要做吗?
      • @abourget:它在 osx 上的工作方式完全相同。你在看什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 2018-07-01
      相关资源
      最近更新 更多