exec.Command questions and how to execute a command line

1,977 views
Skip to first unread message

Stéphane phenetas

unread,
Jul 22, 2015, 4:59:49 PM7/22/15
to golang-nuts
Hello,

I would like to execute a terminal command line through a Go program.

func pingLocalNetwork(){

    tempS, _ := getLocalIPAddress()
    secondTempS := string(tempS[:])
    currentIPAddress := strings.Split(secondTempS,".")

    commandLinePing := fmt.Sprint("nmap -sP " + currentIPAddress[0] + "." + currentIPAddress[1] + "." + currentIPAddress[2] + ".*")
   
    exec.Command("bash", "-c", "nmap -sP 10.11.204.*").Output()
    fmt.Printf("Command : %s\n", commandLinePing)
}

I though of using exec.Command to do so, but apparently nothing happens. I have set up a network listening tool and I can not "see" my command executed.

Is there a go function that allow me to execute any command line I want ?

Thank you.

Nate

unread,
Jul 22, 2015, 5:09:51 PM7/22/15
to golang-nuts
Try CombinedOutput instead of Output to see stderr as well.

Stéphane phenetas

unread,
Jul 22, 2015, 5:20:00 PM7/22/15
to golang-nuts, phen...@gmail.com
I have replaced with CombinedOutput, and this time I get the error "Out = bash: nmap: command not found"

Stéphane phenetas

unread,
Jul 22, 2015, 8:03:17 PM7/22/15
to golang-nuts, phen...@gmail.com
I will ad that I get the error message "exit status 127" when I look what is returned by the exec.Command function.

"Exit status 127" means according to google, that the command is not found and in my case I guess that nmap is not found.
But, I can perfectly execute this command in a terminal. nmap is installed and can be executed with no problem. The only matter is when I need to execute it from Golang.

Ian Lance Taylor

unread,
Jul 22, 2015, 8:23:35 PM7/22/15
to Stéphane phenetas, golang-nuts
On Wed, Jul 22, 2015 at 2:20 PM, Stéphane phenetas <phen...@gmail.com> wrote:
>
> I have replaced with CombinedOutput, and this time I get the error "Out =
> bash: nmap: command not found"

Sounds like something has gone wrong with the PATH search that bash
does to find nmap. See what the value of os.Getenv("PATH") is in your
program. See if nmap can be found on that PATH.

Ian

Stéphane phenetas

unread,
Jul 22, 2015, 8:57:46 PM7/22/15
to golang-nuts, ia...@golang.org
Thank you Ian, so I figured ou that the problem comes from the GUI I use. I use LiteIDE, and the PATH in the GUI is different than the PATH in the terminal.

os.Getenv("PATH") executed in the code in the GUI returns me something different than $PATH executed in the terminal.

I tried my code, executed from the terminal and it works well. How can I be sure that the LiteIDE Path is always the same than the "normal" PATH ?


Thank you.

Nigel Tao

unread,
Jul 22, 2015, 9:33:10 PM7/22/15
to Stéphane phenetas, golang-nuts, Ian Lance Taylor
On Thu, Jul 23, 2015 at 10:57 AM, Stéphane phenetas <phen...@gmail.com> wrote:
> I tried my code, executed from the terminal and it works well. How can I be
> sure that the LiteIDE Path is always the same than the "normal" PATH ?

I don't use LiteIDE myself, so I don't have an answer. Perhaps this
question is best raised in a LiteIDE forum instead of a Go one?

Marvin Renich

unread,
Jul 23, 2015, 8:37:14 AM7/23/15
to golang-nuts
* Stéphane phenetas <phen...@gmail.com> [150722 20:58]:
The typical thing to do is to specify an explicit path in the argument
to exec.Command, e.g. /usr/bin/nmap. For well-known unix programs
installed using your distribution's package manager, this is the best
solution, as it doesn't depend on PATH at all.

Another common solution is to explicitly set PATH at program startup
using os.Setenv to a sane default (possibly allowing it to be specified
in a configuration file).

...Marvin

Mauro Risonho de Paula Assumpção

unread,
Jul 24, 2015, 2:40:32 PM7/24/15
to Marvin Renich, golang-nuts, Mauro Risonho de Paula Assumpção
Hi.

This way to work, but when I add the flag nmap

args := []string{"nmap", "-O", "-A", "127.0.0.1", "-oG", "report-xml-grep"}

It is not generating the XML grep style format.

// In the previous example we looked at
// [spawning external processes](spawning-processes). We
// do this when we need an external process accessible to
// a running Go process. Sometimes we just want to
// completely replace the current Go process with another
// (perhaps non-Go) one. To do this we'll use Go's
// implementation of the classic
// <a href="http://en.wikipedia.org/wiki/Exec_(operating_system)"><code>exec</code></a>
// function.

package main

import "syscall"
import "os"
import "os/exec"

func main() {

    // For our example we'll exec `ls`. Go requires an
    // absolute path to the binary we want to execute, so
    // we'll use `exec.LookPath` to find it (probably
    // `/bin/nmap`).
    binary, lookErr := exec.LookPath("/usr/bin/nmap")
    if lookErr != nil {
        panic(lookErr)
    }

    // `Exec` requires arguments in slice form (as
    // apposed to one big string). We'll give `ls` a few
    // common arguments. Note that the first argument should
    // be the program name.
    // args := []string{"nmap", "-A", "-O", "127.0.0.1"}
    // nmap report formats -oX -oS -oG oN
    args := []string{"nmap", "-O", "-A", "127.0.0.1", "-oG", "report-xml-grep"}
        
    // `Exec` also needs a set of [environment variables](environment-variables)
    // to use. Here we just provide our current
    // environment.
    env := os.Environ()

    // Here's the actual `syscall.Exec` call. If this call is
    // successful, the execution of our process will end
    // here and be replaced by the `/bin/ls -a -l -h`
    // process. If there is an error we'll get a return
    // value.
    execErr := syscall.Exec(binary, args, env)
    if execErr != nil {
        panic(execErr)
    }
}

But the rest of the source code works.

If anyone has any ideas to help us . We would appreciate a lot! :)

@firebitsbr



--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Marvin Renich

unread,
Jul 24, 2015, 4:51:11 PM7/24/15
to golang-nuts
* Mauro Risonho de Paula Assumpção <mauro....@gmail.com> [150724 14:40]:
> This way to work, but when I add the flag nmap
>
> args := []string{"nmap", "-O", "-A", "127.0.0.1", "-oG", "report-xml-grep"}
>
> It is not generating the XML grep style format.

Note that -oG selects greppable format, not XML format.

> // For our example we'll exec `ls`. Go requires an
> // absolute path to the binary we want to execute, so
> // we'll use `exec.LookPath` to find it (probably
> // `/bin/nmap`).
> binary, lookErr := exec.LookPath("/usr/bin/nmap")
> if lookErr != nil {
> panic(lookErr)
> }

In my previous message, I was suggesting to use "/usr/bin/nmap" directly
as the binary, without calling LookPath. The way you have done it has a
minor advantage of letting you quit early if /usr/bin/nmap is not there,
but you would get the error anyway when you call syscall.Exec, so the
call to LookPath is not really necessary.

However, if you wanted to use whatever nmap was in the path, but then
fall back to /usr/bin/nmap if PATH was not set to an appropriate value,
you could call LookPath("nmap") and if you get an error, set binary to
"/usr/bin/nmap" instead of panic'ing and let syscall.Exec give an error
if nmap isn't there.

...Marvin

Reply all
Reply to author
Forward
0 new messages