Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/exec: add convenient, portable way to execute "./foo" (foo in working directory) #20308

Closed
alercah opened this issue May 10, 2017 · 6 comments
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Milestone

Comments

@alercah
Copy link

alercah commented May 10, 2017

exec.Command documentation states: "If name contains no path separators, Command uses LookPath to resolve name to a complete path if possible. Otherwise it uses name directly as Path."

filepath.Join documentation states: "Join calls Clean on the result"

filepath.Clean documentation states: "2. Eliminate each . path name element (the current directory)."

The result is that the most obvious way to execute a command in the working directory, exec.Command(filepath.Join(".", cmd)) is buggy. The result of Join is just cmd, and therefore exec.Command will do a PATH lookup before running the command.

There are four reasonable workarounds. The first is to specify the "/" explicitly and just write exec.Command("./" + cmd) and hope it works. The second is to use filepath.Separator manually, writing exec.Command("." + string(filepath.Separator) + cmd) which is hideous. The third is to create the Command directly. The fourth is to use an absolute path via filepath.Abs, but it requires adding an extra error check.

There should be some facility somewhere to let you do this with less of a headache. Whether this is a new method in the filepath package which allows for creation of paths with a leading "./" or a function in exec to create a Command that does not do PATH resolution, I don't think it is important.

@vcabbage
Copy link
Member

What about filepath.FromSlash("./"+cmd)?

@alercah
Copy link
Author

alercah commented May 10, 2017

Ooh, missed that one. Still feels a little hacky, but it's better than the others!

@vcabbage
Copy link
Member

vcabbage commented May 10, 2017

Another option, which I just now noticed, is to create the *exec.Cmd without the the use of exec.Command(), since the purpose of that function is to resolve the path.

&exec.Cmd{Path: cmd}

From https://golang.org/pkg/os/exec/#Cmd:

    // Path is the path of the command to run.
    //
    // This is the only field that must be set to a non-zero
    // value. If Path is relative, it is evaluated relative
    // to Dir.
    Path string

   ...

    // Dir specifies the working directory of the command.
    // If Dir is the empty string, Run runs the command in the
    // calling process's current directory.
    Dir string

Edit: exec.Command() properly sets Cmd.Args to []string{cmd, arg1, arg2, ...} as well, so there is one extra step if you have arguments to pass.

@bradfitz bradfitz changed the title There is no convenient way to execute a command in the working directory. os/exec: add convenient way to execute a command in the working directory? May 10, 2017
@bradfitz bradfitz added this to the Unplanned milestone May 10, 2017
@bradfitz bradfitz added the NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made. label May 10, 2017
@tejasmanohar
Copy link

Personally, I don't feel like we need a helper function in os/exec that depends on os.Getwd

@mvdan
Copy link
Member

mvdan commented May 10, 2017

I've only needed to do this a few times and I just used a full path with a directory like os.Getwd. That's at most a few extra lines, and in my opinion it's self-explanatory and simple.

I feel like adding extra API or magic to os/exec to avoid a bit of typing is unnecessary.

@rsc rsc changed the title os/exec: add convenient way to execute a command in the working directory? os/exec: add convenient, portable way to execute "./foo" (foo in working directory) May 22, 2017
@rsc
Copy link
Contributor

rsc commented May 22, 2017

This seems like a non-problem. People can write "./foo", which works everywhere already, or they can use a full path with os.Getwd, as @mvdan suggests. If this really happens a lot, then instead of

"." + string(filepath.Separator) + cmd

define

const dotSlash = "." + string(filepath.Separator)

and write dotSlash + cmd.

@rsc rsc closed this as completed May 22, 2017
@golang golang locked and limited conversation to collaborators May 22, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
FrozenDueToAge NeedsDecision Feedback is required from experts, contributors, and/or the community before a change can be made.
Projects
None yet
Development

No branches or pull requests

7 participants