golang executable file not found in $PATH

webyh · · 4861 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

最近使用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}
	}
	//遍历环境变量里面所有的路劲,然后寻找path
	for _, dir := range strings.Split(pathenv, ":") {
		if dir == "" {
			// Unix shell semantics: path element "" means "."
			dir = "."
		}
		path := dir + "/" + file
		if err := findExecutable(path); err == nil {
			return path, nil
		}
	}
	return "", &Error{file, ErrNotFound}
}

如果是docker,并且配置在/usr/bin/docker则输入docker会返回具体的执行path:/usr/bin/docker

本文来自:开源中国博客

感谢作者:webyh

查看原文:golang executable file not found in $PATH

入群交流(和以上内容无关):Go中文网 QQ 交流群:798786647 或加微信入微信群:274768166 备注:入群;关注公众号:Go语言中文网

4861 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传