Skip to content

os/exec: Command with arguments does not behave well if those are not trimmed #17041

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

Closed
AnomalRoil opened this issue Sep 9, 2016 · 2 comments

Comments

@AnomalRoil
Copy link

What version of Go are you using (go version)?

go1.6.2

What operating system and processor architecture are you using (go env)?

linux/amd64

What did you do?

I'm trying to run an external binary through the os/exec package and feed it with an argument (coming from another external binary, but it's a detail)
Here is the minimal example I could build after finally finding the problem :

 package main

 import (
     "fmt"
     "os/exec"
 )

 func main() {
 cmd := exec.Command("ls","-l ")
 _ , err := cmd.Output()
 if err != nil {
     fmt.Println(err)
 }
 fmt.Println("input:", cmd)
 }

What did you expect to see?

I would expect the Command to run as if it were typed in a shell, or to exit with an explicit error in case of a problem.

What did you see instead?

The Output() function exited with an "Exit status 1" error or an "Exit status 2" one depending on the binary it was given and even when panicking on its error, the trace is of no use.

And actually in my case it seems like it were some white-space which was causing the problem.
Here is my real case : I'm feeding to a Command an argument coming from the Output of another Command, this other program outputs its result through a Printf ("%s\n", result) and it causes the exact same problem to exec : it fails when I try to run using this output fetched from .Output() as an argument.

I tried to take a look at the code of the exec package but I wasn't able to spot why it is failing like this.

I think it would be a good idea to explicitly enforce in the Documentation that white-spaces in an argument are to be avoided and to implement more explicit errors maybe for this case ?

@bradfitz
Copy link
Contributor

bradfitz commented Sep 9, 2016

I would expect the Command to run as if it were typed in a shell

Sorry, that's not how this package works.

You also can't do redirection to files, piping into other programs, etc.

We never mention anywhere in the docs the word "shell", which at least to me suggests it doesn't act like a shell.

I'm inclined to do nothing here documentation-wise, but I'm open to disagreements. We're definitely not changing the behavior to trim.

@bradfitz bradfitz closed this as completed Sep 9, 2016
@AnomalRoil
Copy link
Author

Alright, I must confess I should not have been expecting it to behave like a shell, since it does not make so much sense indeed. But still, here is what I was expecting, I think :
When calling for example /bin/ls with "-l " as argument -- remark the space at the end --, instead of just an "exit status 2" error, I would expect it to output the error as /bin/ls does :
/bin/ls: invalid option -- ' '

But then I realized that .CombinedOutput() is doing exactly this, so I guess I should use CombinedOutput when doing debugging, it would have saved me hours. Hope someone will find this post helpful once.

In the end, effectively the only thing I missed documentation-wise, was an explicit mention of Output() ignoring the Stderr in case of errors. But I won't argue it is necessary in the documentation.

Sorry for bothering you and many thanks Brad!

@golang golang locked and limited conversation to collaborators Sep 12, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants