script icon indicating copy to clipboard operation
script copied to clipboard

String method return a new line when followed by Exec

Open ifraixedes opened this issue 2 years ago • 3 comments

Calling String followed by Exec returns a string ending with a new line (i.e. \n).

Example:

out, err := script.Exec("echo hello").String()
if err != nil {
	log.Fatal(err)
}

fmt.Printf("%q\n", out)

It prints: "hello\n"

Is this intended or the \n shouldn't be there?

If I'm not mistaken the issue is that os/exec.Command returns it. Execute this example

package main

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

  func main() {
    out := &bytes.Buffer{}

    cmd := exec.Command("echo", "hello")

    cmd.Stdout = out
    err := cmd.Start()
    if err != nil {
      log.Fatal(err)
    }

    cmd.Wait()

    fmt.Printf("%q\n", out.String())
  }

And you see that it prints: "hello\n"

ifraixedes avatar Dec 14 '22 16:12 ifraixedes

If you run the command echo hello in your terminal, you'll see that it prints exactly hello\n.

bitfield avatar Dec 14 '22 16:12 bitfield

Right. The thing is that I ran into this issue when I was trying to do this shell

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

And how I'm doing with script is

arch, err := script.Exec("dpkg --print-architecture").String()
if err != nil {
	log.Fatal(err)
}

versionName, err := script.Exec("lsb_release -cs").String()
if err != nil {
	log.Fatal(err)
}

_, err := exec.Echo(fmt.Sprintf("deb [arch=%s signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian  %s stable", arch, versionName)).Exec("sudo tee /etc/apt/sources.list.d/docker.list").String()
if err != nil {
	log.Fatal(err)
}

Because Exec("dpkg --print-architecture") and Exec("lsb_release -cs") have a newline at the end, it doesn't work as expected and I have to trim the \n for each result.

ifraixedes avatar Dec 15 '22 10:12 ifraixedes

If you're looking to add a newline -- use printf instead of echo:

script.Exec(`printf "Hello There\n\n\n\n"`).Stdout() 

If you're looking to remove the newline from the end of the string you can do it like this:

versionName, err := script.Exec("lsb_release -cs").String()
if err != nil {
	log.Fatal(err)
}
versionName=strings.TrimSpace(versionName) 

That will remove all whitespace from both sides of the string.

rmasci avatar Mar 21 '23 12:03 rmasci