以编程方式可靠地在容器中检索go可执行文件的路径,而无需使用Go

以编程方式可靠地在容器中检索go可执行文件的路径,而无需使用Go

问题描述:

How can I retrieve the path to the go binary in a container that does not have which programatically?

One option would be to execute which go as follows:

bytes, err := exec.Command("which", "go").Output()

However, I would like to not depend on which being available. Does go provide any in-built mechanism to retrieve this and if not, what is the alternative apart from having the user pass in the path themselves?

如何在没有容器的容器中检索 go code>二进制文件的路径 哪个 code> 以编程方式 em>? p>

一个选项是执行如下的 where code>: p>

  bytes,err:= exec.Command(“ which”,“ go”)。Output()
  code>  pre> 
 
 

我不希望依赖哪个 code>可用。 go是否提供任何内置的机制来检索此内容?如果没有,除了让用户自己通过路径之外,还有什么其他选择? p> div>

From the man page of which:

Which takes one or more arguments. For each of its arguments it prints to stdout the full path of the executables that would have been executed when this argument had been entered at the shell prompt. It does this by searching for an executable or script in the directories listed in the environment variable PATH using the same algorithm as bash(1).

Go's os/exec.LookPath function is very close to this functionality:

LookPath searches for an executable named file in the directories named by the PATH environment variable. If file contains a slash, it is tried directly and the PATH is not consulted. The result may be an absolute path or a path relative to the current directory.

Use path/filepath.Abs if you need a guaranteed absolute path.

I don't expect this to be the best answer, but it is one that I just found. I was hoping for more of a go-specific one, but in the meantime type in linux is a default built-in one available in bash and sh (alpine).

You can test this yourself by running type type which yields:

type is a shell builtin

The usage in go would look like this:

b, err := exec.Command("type", "go").Output()

if err != nil {
    /* 'type' is not available on the O/S */
}

goPath := strings.TrimPrefix(strings.TrimSuffix(string(b), "
"), "go is ")

The reason the Trim functions are required is because the output would look like this:

go is /usr/local/go/bin/go

This isn't the nicest way of going about it, but it works.