0

i want run multiple command in "os/exec" in one process, as you see below some command like "cd" not worked.

func main()  {
cmd := exec.Command("ls")
cmdOutput := &bytes.Buffer{}
cmd.Stdout = cmdOutput
err := cmd.Run()
fmt.Print(string(cmdOutput.Bytes()))

fmt.Println("..........  cd   .........")
cdOutput := &bytes.Buffer{}
cdcomand:=exec.Command("cd","model")
cdcomand.Stdout = cdOutput
err = cdcomand.Run()
fmt.Print(string(cdOutput.Bytes()))
fmt.Println(".......... ls .........")
lsOutput := &bytes.Buffer{}
lscmd:=exec.Command("ls")
lscmd.Stdout = lsOutput

err = lscmd.Run()
if err != nil {
    os.Stderr.WriteString(err.Error())
}
fmt.Print(string(lsOutput.Bytes()))}


i try with another way:
package main

import (
"os/exec"
"bytes"
"os"
"fmt"
)

func main()  {
cmd := exec.Command("ls")
cmdOutput := &bytes.Buffer{}
cmd.Stdout = cmdOutput
err := cmd.Run()
fmt.Print(string(cmdOutput.Bytes()))

fmt.Println("..........  cd and ls   .........")
cdOutput := &bytes.Buffer{}
cdcomand:= exec.Command("sh", "-c", "ls && cd model")
cdcomand.Stdout = cdOutput
err = cdcomand.Run()
fmt.Print(string(cdOutput.Bytes()))
fmt.Println(".......... ls .........")
lsOutput := &bytes.Buffer{}
lscmd:=exec.Command("ls")
lscmd.Stdout = lsOutput

err = lscmd.Run()
if err != nil {
    os.Stderr.WriteString(err.Error())
}
fmt.Print(string(lsOutput.Bytes()))
}

it did not work too.

in cmd document writes:

A Cmd cannot be reused after calling its Run, Output or CombinedOutput methods.

i've searched all tuts and docs for a way to do this, but i could not find any things. there was no solution in Executing external commands in Go article and advanced command execution in Go with os

each cmd command execute in different process so command like "cd" will not change directory .
is there any way run multiple command "os/exec" in one proccess in golang?

Ali Zohrevand
  • 393
  • 4
  • 20
  • 2
    A single process can create and run multiple `Cmd` objects. – Charlie Tumahai Jun 09 '18 at 18:58
  • i could not find any example or tuts for run or add Cmd objects to process obj, could you please make an example ? – Ali Zohrevand Jun 09 '18 at 20:12
  • i am familiar with cmd object, i want all of cmd execution run in same process, i've updated my question – Ali Zohrevand Jun 09 '18 at 21:35
  • If all you want is to change directory, then set [Cmd.Dir](https://godoc.org/os/exec#Cmd.Dir). Otherwise, run a shell to execute multiple commands from a child process. Note that the shell will start a process for each command. – Charlie Tumahai Jun 09 '18 at 21:54
  • my only purpose is not "Cd" command, because of create and start new process for each command, command like "cd" will not work, i am looking for executing all cmd in one process. – Ali Zohrevand Jun 09 '18 at 23:06
  • i am develoning a reverse shell or some thing like ssh, user send command like "ls" , "cd" etc. and client execute them and reply response of that command. command like cd did not work. – Ali Zohrevand Jun 09 '18 at 23:15
  • yes, my last choice is develop built in cd, what do you mean run shell? i search for this key word and os/exec was only way! how run shell and does it return output of each command? thanks for taking time and helping. – Ali Zohrevand Jun 09 '18 at 23:33
  • 1
    How to run shell: See existing answer to this question and https://stackoverflow.com/questions/34458625/. – Charlie Tumahai Jun 10 '18 at 05:06

1 Answers1

3

Yes!

You could use sh -c "ls && cd model"

cmd := exec.Command("sh", "-c", "ls && cd model")
cmd.Stdout = &stdout
cmd.Stderr = &stderr
err = cmd.Run()

On ubuntu

$ man sh

DASH(1)                                                              BSD General Commands Manual                                                              DASH(1)

NAME
     dash — command interpreter (shell)

           -c               Read commands from the command_string operand instead of from the standard input.  Special parameter 0 will be set from the command_name
                            operand and the positional parameters ($1, $2, etc.)  set from the remaining argument operands.

An example using:

$ go version
go version go1.10.2 linux/amd64

// cmd/test/main.go

package main

import (
        "bytes"
        "os/exec"
        "fmt"
)


func main() {
        var stdout, stderr bytes.Buffer
        cmd := exec.Command("sh", "-c", "echo 'hello' && echo 'hi'")
        cmd.Stdout = &stdout
        cmd.Stderr = &stderr
        err := cmd.Run()
        fmt.Println(err)
        out := stdout.String() + stderr.String()
        fmt.Printf(out)
}

$ go run cmd/test/main.go
<nil>
hello
hi
dm03514
  • 54,664
  • 18
  • 108
  • 145