美文网首页简书Go语言专栏
go语言syscall.Exec的用法

go语言syscall.Exec的用法

作者: CodingCode | 来源:发表于2019-03-05 14:35 被阅读77次

    go语言syscall.Exec的用法

    背景

    在docker应用开发的时候,我们经常看到container的启动脚本docker-entrypoint.sh的最后一句话会是”exec $@“, 这句话有什么意义呢?

    shell里面的exec

    exec会执行参数指定的命令,但是并不创建新的进程,只在当前进程空间内执行,即替换当前进程的执行内容,他们重用同一个进程号PID。

    go语言syscall.Exec完成同样的功能

    package main
    
    import "time"
    import "syscall"
    import "os"
    import "os/exec"
    
    func main() {
    
        binary, err := exec.LookPath("sleep")
        if err != nil {
            panic(err)
        }
    
        args := []string{"sleep", "10"}
    
        env := os.Environ()
    
        time.Sleep(10 * time.Second)
    
        if err := syscall.Exec(binary, args, env); err != nil {
            panic(err)
        }
    }
    

    syscall.Exec需要三个参数:

    1. 第一个参数是可执行文件的路径,注意不会自动从PATH下面去搜索,所以:
      1.1 要么是显式的指定全路径:/path/to/executable
      1.2 要么是显式的指定相对路径: ./relpath/to/executable
      1.3 要么通过exec.LookPath从PATH里面搜索出来,如本例子。
    2. 第二个参数是参数列表
      2.1 注意args[0]是可执行程序名,这个内容会显示在ps -ef的输出中。用户可以改这个值,例如明明执行的是/usr/bin/sleep的可执行程序,但是这里可以改成任意字符串,例如ls,这样用户在ps -ef查看到的就是ls的命令在运行,而不是sleep命令,混淆用户。
      2.2 后面是正常的参数。
    3. 第三个参数是环境变量
      3.1 如果没有传,那么不会自动继承caller的环境变量的。

    所以syscall.Exec只能是main函数的最后一条指令,它后面的代码不会被执行到。

    相关文章

      网友评论

        本文标题:go语言syscall.Exec的用法

        本文链接:https://www.haomeiwen.com/subject/bxanuqtx.html