How to run this system command on golang? [duplicate] - go

This question already has answers here:
fork/exec . no such file or directory exit status 1
(3 answers)
call 'go build' command from golang os.exec
(1 answer)
Why is this curl command not working?
(2 answers)
calling command with some arguments works but not with others but works from console
(1 answer)
How to pass a flag to a command in go lang?
(1 answer)
Closed 2 days ago.
This post was edited and submitted for review 2 days ago.
I am trying to run this command using golang
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
var (
host = "rtsp://localhost:8554/test"
projectName = "test"
gcpRegion = "test"
vertexStreams = "test"
)
// Run the system terminal command.
validFormattedString := fmt.Sprintln("vaictl", "-p", projectName, "-l", gcpRegion, "-c", "application-cluster-0 --service-endpoint visionai.googleapis.com send rtsp to streams", vertexStreams, "--rtsp-uri", host)
runSystemTerminalCommand(validFormattedString)
}
// Run a command in the system terminal.
func runSystemTerminalCommand(content string) {
cmd := exec.Command(content)
err := cmd.Run()
if err != nil {
log.Fatalln(err)
}
}
Error:
2023/02/17 21:02:16 fork/exec vaictl -p github-code-snippets -l us-central1 -c application-cluster-0 --service-endpoint visionai.googleapis.com send rtsp to streams dji-stream-0 --rtsp-uri rtsp://Administrator:Password#localhost:8554/test : no such file or directory
The application is installed in the system but i am still getting the error that "no such file or directory".
FIX:
This is the fix for the issue.
Everything must be passed on its own for it to work.
package main
import (
"log"
"os/exec"
)
func main() {
var (
host = "rtsp://Administrator:Password#localhost:8554/test"
projectName = "github-code-snippets"
gcpRegion = "us-central1"
vertexStreams = "dji-stream-0"
)
// Run the system terminal command.
cmd := exec.Command("vaictl", "-p", projectName, "-l", gcpRegion, "-c", "application-cluster-0", "--service-endpoint", "visionai.googleapis.com", "send", "rtsp", "to", "streams", vertexStreams, "--rtsp-uri", host)
err := cmd.Run()
if err != nil {
log.Fatalln(err)
}
}

Related

How to properly "go build" using exec.Command with many arguments?

I'm trying to compile a go package using exec.Command. I was successful with the arguments being "go" and "build" as such below:
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
out, err := exec.Command("go", "build").Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(out)
}
However, while trying to perform a "go build" with more arguments it seems that I'm doing something wrong? This is what my code looks like:
package main
import (
"fmt"
"log"
"os/exec"
)
func main() {
out, err := exec.Command("set", "GOOS=js&&", "set", "GOARCH=wasm&&", "go", "build", "-o", "C:/Users/Daniel/Desktop/go-workspace/src/sandbox/other/wasm/assets/json.wasm", "kard").Output()
if err != nil {
log.Fatal(err)
}
fmt.Println(out)
}
The output is exec: "set": executable file not found in %PATH%
The normal command I would perform for this in the command line would be set GOOS=js&& set GOARCH=wasm&& go build -o C:\Users\Daniel\Desktop\go-workspace\src\sandbox\other\wasm\assets\json.wasm kard.
I assume there is something I'm misunderstanding with using exec.Command? I really appreciate any support.
The application uses shell syntax to set the environment variables, but the exec package does not use a shell (unless the command that you are running is a shell).
Use the command environment to specify the environment variables for the exec'ed command.
The go build does not normally write to stdout, but it does write errors to stderr. Use CombinedOutput instead of Output to easily capture error text.
cmd := exec.Command("go", "build", "-o", "C:/Users/Daniel/Desktop/go-workspace/src/sandbox/other/wasm/assets/json.wasm", "kard")
cmd.Env = []string{"GOOS=js", "GOARCH=wasm"}
out, err := cmd.CombinedOutput()
if err != nil {
fmt.Printf("%v: %s\n", err, out)
}

exec : hangman.go Executable file not found in $PATH

i have problem trying to run my hangman game (hangman.go) into an other program (server.go)
package main
import (
"log"
"os/exec"
)
func main() {
cmd := exec.Command("hangman.go")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}
Ive tried to build a hangman.exe too but i still have the same error when i run server.go
2021/12/03 10:42:19 exec: "hangman.go": executable file not found in $PATH
exit status 1
You have two problems:
You cannot execute a *.go source file, you must use your compiled hangman.exe.
If your command "contains no path separators" then exec.Command() looks for the command in your PATH environment variable, it is not in any of those directories so it is not run. You need to specify a relative or fully qualified path to the file, if it is in the current working directory this can just be .\hangman.exe (or ./hangman on unix like systems):
package main
import (
"log"
"os/exec"
)
func main() {
cmd := exec.Command(".\hangman.exe")
err := cmd.Run()
if err != nil {
log.Fatal(err)
}
}

exec to pod using client-go [duplicate]

This question already has answers here:
example of exec in k8s's pod by using go client
(3 answers)
Closed 11 months ago.
I am new to go and client-go :).
I saw this function where I can use it to send a command or exec to a pod with an interactive terminal. In the below, I need to know what parameters should I provide to call it from func main() as I can see it requires "config *restclient.Config" which I do not understand. Any example or a starting point ?
PS. I know how to create the clientset to authenticate using kubeconfig. just need to know what parameters this will require and how to call it from the main function.
package main
import (
"io"
v1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/remotecommand"
)
//ExecCmdExample exec command on specific pod and wait the command's output.
func ExecCmdExample(client kubernetes.Interface, config *restclient.Config, podName string,
command string, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
cmd := []string{
"sh",
"-c",
command,
}
req := client.CoreV1().RESTClient().Post().Resource("pods").Name(podName).
Namespace("default").SubResource("exec")
option := &v1.PodExecOptions{
Command: cmd,
Stdin: true,
Stdout: true,
Stderr: true,
TTY: true,
}
if stdin == nil {
option.Stdin = false
}
req.VersionedParams(
option,
scheme.ParameterCodec,
)
exec, err := remotecommand.NewSPDYExecutor(config, "POST", req.URL())
if err != nil {
return err
}
err = exec.Stream(remotecommand.StreamOptions{
Stdin: stdin,
Stdout: stdout,
Stderr: stderr,
})
if err != nil {
return err
}
return nil
}
I was able to resolve this. the question can be closed.
Edit:
you can look at the code here:
https://github.com/mohatb/kubego

Execute an external command and return its output

I'm trying to execute a linux command and convert the output to an int. This is my current code:
package main
import (
"os/exec"
"os"
"strconv"
_"fmt"
"log"
"bytes"
)
func main(){
cmd := exec.Command("ulimit", "-n")
cmdOutput := &bytes.Buffer{}
cmd.Stdout = cmdOutput
err := cmd.Run()
if err != nil {
os.Stderr.WriteString(err.Error())
}
count, err := strconv.Atoi( string(cmdOutput.Bytes()) )
if err != nil {
log.Fatal(err)
}
if count <= 1024 {
log.Fatal("This machine is not good for working!!!")
}
}
This is my current error:
2018/10/12 14:37:27 exec: "ulimit -n": executable file not found in
$PATH
I don't understand what this error means and how I can fix it.
There is no ulimit program in linux that you can run.
ulimit is a builtin of a shell. So you need to run a shell and have the shell run its internal ulimit command.
cmd := exec.Command("/bin/sh", "-c" "ulimit -n")
you will also have to remove the newline from the output of the ulimit command, e.g.
count, err := strconv.Atoi( strings.Trim(string(cmdOutput.Bytes()),"\n"))
A better alternative is to retreive these limits via the syscall API in go, see How to set ulimit -n from a golang program? - the accepted answer first gets and prints the current limit.

How can I source a shell script using Go?

I want to source shell scripts using Go. Ideally the following code
cmd := exec.Command("/bin/bash", "source", file.Name())
but, I know that "source" is a bash built-in function, not an executable.
However, I have found some ways to mimic this behavior in Python:
http://pythonwise.blogspot.fr/2010/04/sourcing-shell-script.html
Unfortunately, I don't know how to translate this in Go. Does anyone have an idea ?
Thanks !
You can set environmental variables when running a program using exec:
cmd := exec.Command("whatever")
cmd.Env = []string{"A=B"}
cmd.Run()
If you really need source then you can run your command through bash:
cmd := exec.Command("bash", "-c", "source " + file.Name() + " ; echo 'hi'")
cmd.Run()
Check out this library for a more full-featured workflow: https://github.com/progrium/go-basher.
Update: Here's an example that modifies the current environment:
package main
import (
"bufio"
"bytes"
"io/ioutil"
"log"
"os"
"os/exec"
"strings"
)
func main() {
err := ioutil.WriteFile("example_source", []byte("export FOO=bar; echo $FOO"), 0777)
if err != nil {
log.Fatal(err)
}
cmd := exec.Command("bash", "-c", "source example_source ; echo '<<<ENVIRONMENT>>>' ; env")
bs, err := cmd.CombinedOutput()
if err != nil {
log.Fatalln(err)
}
s := bufio.NewScanner(bytes.NewReader(bs))
start := false
for s.Scan() {
if s.Text() == "<<<ENVIRONMENT>>>" {
start = true
} else if start {
kv := strings.SplitN(s.Text(), "=", 2)
if len(kv) == 2 {
os.Setenv(kv[0], kv[1])
}
}
}
}
log.Println(os.Getenv("FOO"))
I have recently added such a utility function to my shell/bash Golang library:
https://godoc.org/mvdan.cc/sh/shell#SourceFile
For example, you could do:
vars, err := shell.SourceFile("foo.sh")
if err != nil { ... }
fmt.Println(vars["URL"].Value)
// http://the.url/value
It's decently safe, because it never actually calls bash nor any other program. It parses the shell script, then interprets it. But when interpreting, it has a whitelist of what files the script can open and what programs the script can execute.
The interpreter also has a context.Context, so you can set a timeout if you want to be protected against forever loops or other bad code.

Resources