Passing variable as argument for exec.Command() - go

I want to read user input and use it as an argument for a command. I got this code:
package main
import (
"bufio"
"fmt"
"log"
"os"
"os/exec"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter img path: ")
imgPath, _ := reader.ReadString('\n')
args := []string{imgPath, "stdout", "-l spa+eng"}
out, err := exec.Command("tesseract", args...).Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}
But when I execute it it outputs an error saying exit status 1.
If instead of using the variable imgPath as an argument I write some text directly into the array it works like a charm.

The following code returns a line with the delimiter (I work on Windows and its EOL is '\r\n'), something that wasn't shown when I printed it on the console.
reader := bufio.NewReader(os.Stdin)
imgPath, _ := reader.ReadString('\n')
In my case it ended up working after I trimmed '\r\n' from the input:
package main
import (
"bufio"
"fmt"
"log"
"os"
"os/exec"
)
func main() {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter img path: ")
imgPath, _ := reader.ReadString('\n')
imgPath= strings.TrimRight(line, "\r\n")
args := []string{imgPath, "stdout", "-l spa+eng"}
out, err := exec.Command("tesseract", args...).Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(string(out))
}

Related

Golang Error is <nil> instead of EOF when Ctrl-D is pressed on Mac

My code is as follows. It is a simple echo program
package main
import (
"fmt"
"io"
"log"
"os"
)
func main() {
mustCopy(os.Stdout, os.Stdin)
}
func mustCopy(dst io.Writer, src io.Reader) {
_, err := io.Copy(dst, src)
fmt.Println(err)
if err != nil {
log.Fatal(err)
}
}
I also checked keyboard mappings for EOF on mac by using stty all it gives ^D as eof
Output of program is as follows
a
b
b
c
c
<nil>
As per the docs golang.org/pkg/io/#Copy and pointed by #BrunoReis Copy is behaving as expected as the err will be nil if Copy is terminated due to EOF
In the following, we replace io.Copy with io.CopyN to set expectation higher and close early.
package main
import (
"fmt"
"io"
"log"
"os"
)
func main() {
mustCopy(os.Stdout, os.Stdin)
}
func mustCopy(dst io.Writer, src io.Reader) {
_, err := io.CopyN(dst, src, 2000) // 2000 is arbitrary, just big enough
fmt.Println(err)
if err != nil {
log.Fatal(err)
}
}
Example run:
a
a
b
b
c
c
EOF
2020/05/26 02:26:04 EOF
exit status 1

How to read a command output with its color attributes?

Is it possible to read a commands output with its color attributes. I mean, can we read the actual escape sequences.
for instance;
A command output is red colored:
Hello
I want to read it as :
\033[31;1;4mHello\033[0m
Currently I am reading it like:
func stat(hash string) string {
cmd := exec.Command("git", "show", "--stat", hash)
out, err := cmd.Output()
if err != nil {
return err.Error()
}
return string(out)
}
Use the github.com/creack/pty library to run the command in a pty
This works for me
The escape sequences are visible in the output
package main
import (
"github.com/creack/pty"
"io"
"os"
"os/exec"
)
func main() {
hash := os.Args[1]
cmd := exec.Command("git", "show", "--stat", hash)
f, err := pty.Start(cmd)
if err != nil {
panic(err)
}
io.Copy(os.Stdout, f)
}

Unexpected StrComp result when string is sent from golang app

In my code below I've set up a ReadString which reads user input and passes it along in a exec.Command.
This works just fine, but when I try to compare the string with a hardcoded string in vbscript (in this case I'm comparing it to "hello") it always fails even when the user input is "hello" as well.
If I just run the vbscript through the command line like this however...
cscript.exe script.vbs hello
...then the StrComp works as intended so I suspect that it's either a data type issue or there's some extra character that's passed along in the golang app.
Here's the main.go:
package main
import (
"fmt"
"os/exec"
"bufio"
"os"
)
func main() {
buf := bufio.NewReader(os.Stdin)
fmt.Print("Type something: ")
text, err := buf.ReadString('\n')
if err != nil {
fmt.Println(err)
} else {
args := []string{"./script.vbs", string(text)}
exec.Command("cscript.exe", args...).Run()
}
}
And here's the script.vbs
MsgBox(WScript.Arguments(0))
If StrComp(WScript.Arguments(0), "hello") = 0 Then
MsgBox("it's the same")
Else
MsgBox("It's not the same...")
End If
When working with windows, line endings are "\r\n". I don't know whether ReadString() should remove the delimiter, but even then text will contain an invisible \r. Use strings.TrimSpace to be on the save side:
package main
import (
"fmt"
"os/exec"
"bufio"
"os"
"strings"
)
func main() {
buf := bufio.NewReader(os.Stdin)
fmt.Print("Type something: ")
text, err := buf.ReadString('\n')
fmt.Printf("0 got: %T %v %q\r\n", text, text, text)
text = strings.TrimSpace(text)
fmt.Printf("1 got: %T %v %q", text, text, text)
if err != nil {
fmt.Println(err)
} else {
args := []string{"./script.vbs", string(text)}
exec.Command("cscript.exe", args...).Run()
}
}
output (of main; use your imagination for the VBScript MsgBoxes):
main
Type something: hello
0 got: string hello
"hello\r\n"
1 got: string hello "hello"

strconv.Atoi in Go (Basic calculator)

I'm trying to make a basic adding calculator in Go (complete noob here), but every time I'm getting an output of 0.
This is the code:
package main
import (
"fmt"
"strconv"
//"flag"
"bufio"
"os"
)
func main(){
reader := bufio.NewReader(os.Stdin)
fmt.Print("What's the first number you want to add?: ")
firstnumber, _ := reader.ReadString('\n')
fmt.Print("What's the second number you want to add?: ")
secondnumber, _ := reader.ReadString('\n')
ifirstnumber, _ := strconv.Atoi(firstnumber)
isecondnumber, _ := strconv.Atoi(secondnumber)
total := ifirstnumber + isecondnumber
fmt.Println(total)
}
bufio.Reader.ReadString() returns data up until and including the separator. So your string actually ends up being "172312\n". strconv.Atoi() doesn't like that and returns 0. It actually returns an error but you're ignoring it with _.
You can see what happens with this example:
package main
import (
"fmt"
"strconv"
)
func main(){
ifirstnumber, err := strconv.Atoi("1337\n")
isecondnumber, _ := strconv.Atoi("1337")
fmt.Println(err)
fmt.Println(ifirstnumber, isecondnumber)
}
You can trim the newlines with strings.Trim(number, "\n").

In Golang I'm getting the record through exe command. how to print it line by line?

I want to print the results line by line.
I'm getting the record's data through exe command.
Here is the code:
package main
import (
"bufio"
"fmt"
"os/exec"
)
func main() {
app := "df"
//app := "buah"
arg0 := "-h"
cmd := exec.Command(app, arg0)
stdout, err := cmd.Output()
if err != nil {
println(err.Error())
return
}
// bytes, _ := ioutil.ReadAll(stdout)
s := bufio.NewScanner(stdout)
fmt.Println(s)
}
Thanks in advance.
Any help is greatly appreciated.
It is simple:
a := []string{}
for s.Scan() {
a = append(a, s.Text())
}
And You have a slice of strings.

Resources