這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
最近使用docker,遇見executable file not found in $PATH,深究一下源碼,追溯到golang內建包,看代碼
//尋找可執行檔檔案,取檔案的mode(二進位形式)func findExecutable(file string) error {d, err := os.Stat(file)if err != nil {return err}//看屬性if m := d.Mode(); !m.IsDir() && m&0111 != 0 {return nil}return os.ErrPermission}來看看linux手冊上面的mode數值S_IFMT 0170000 檔案類型的位遮罩 S_IFSOCK 0140000 socket S_IFLNK 0120000 符號連結(symbolic link) S_IFREG 0100000 一般檔案 S_IFBLK 0060000 區塊裝置(block device) S_IFDIR 0040000 目錄 S_IFCHR 0020000 字元裝置(character device) S_IFIFO 0010000 先進先出(fifo) S_ISUID 0004000 檔案的(set user-id on execution)位 S_ISGID 0002000 檔案的(set group-id on execution)位 S_ISVTX 0001000 檔案的sticky位 S_IRWXU 00700 檔案所有者的遮罩值(即所有許可權值) S_IRUSR 00400 檔案所有者具可讀取許可權 S_IWUSR 00200 檔案所有者具可寫入許可權 S_IXUSR 00100 檔案所有者具可執行許可權 S_IRWXG 00070 使用者組的遮罩值(即所有許可權值) S_IRGRP 00040 使用者組具可讀取許可權 S_IWGRP 00020 使用者組具可寫入許可權 S_IXGRP 00010 使用者組具可執行許可權 S_IRWXO 00007 其他使用者的遮罩值(即所有許可權值) S_IROTH 00004 其他使用者具可讀取許可權 S_IWOTH 00002 其他使用者具可寫入許可權 S_IXOTH 00001 其他使用者具可執行許可權
再看看golang尋找可執行檔
var ErrNotFound = errors.New("executable file not found in $PATH")func LookPath(file string) (string, error) {// NOTE(rsc): I wish we could use the Plan 9 behavior here// (only bypass the path if file begins with / or ./ or ../)// but that would not match all the Unix shells.if strings.Contains(file, "/") {err := findExecutable(file)if err == nil {return file, nil}return "", &Error{file, err}}pathenv := os.Getenv("PATH") if pathenv == "" {return "", &Error{file, ErrNotFound}}//遍曆環境變數裡面所有的路勁,然後尋找pathfor _, dir := range strings.Split(pathenv, ":") {if dir == "" {// Unix shell semantics: path element "" means "."dir = "."}path := dir + "/" + fileif err := findExecutable(path); err == nil {return path, nil}}return "", &Error{file, ErrNotFound}}
如果是docker,並且配置在/usr/bin/docker則輸入docker會返回具體的執行path:/usr/bin/docker