go語言syscall.Exec的用法
背景
在docker應(yīng)用開發(fā)的時候疏虫,我們經(jīng)常看到container的啟動腳本docker-entrypoint.sh的最后一句話會是”exec $@“, 這句話有什么意義呢菱皆?
shell里面的exec
exec會執(zhí)行參數(shù)指定的命令颖御,但是并不創(chuàng)建新的進(jìn)程,只在當(dāng)前進(jìn)程空間內(nèi)執(zhí)行汹胃,即替換當(dāng)前進(jìn)程的執(zhí)行內(nèi)容上沐,他們重用同一個進(jìn)程號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需要三個參數(shù):
- 第一個參數(shù)是可執(zhí)行文件的路徑,注意不會自動從PATH下面去搜索,所以:
1.1 要么是顯式的指定全路徑:/path/to/executable
1.2 要么是顯式的指定相對路徑: ./relpath/to/executable
1.3 要么通過exec.LookPath從PATH里面搜索出來龄广,如本例子硫眯。 - 第二個參數(shù)是參數(shù)列表
2.1 注意args[0]是可執(zhí)行程序名,這個內(nèi)容會顯示在ps -ef的輸出中择同。用戶可以改這個值两入,例如明明執(zhí)行的是/usr/bin/sleep的可執(zhí)行程序,但是這里可以改成任意字符串敲才,例如ls裹纳,這樣用戶在ps -ef查看到的就是ls的命令在運行,而不是sleep命令紧武,混淆用戶剃氧。
2.2 后面是正常的參數(shù)。 - 第三個參數(shù)是環(huán)境變量
3.1 如果沒有傳阻星,那么不會自動繼承caller的環(huán)境變量的朋鞍。
所以syscall.Exec只能是main函數(shù)的最后一條指令,它后面的代碼不會被執(zhí)行到迫横。