1

I have made an ssh connection by using the go and the ssh package along which I am using stdout and stdin pipes to ensure that I can received and send multiple commands to an odroid board.

My implementation works for standard ssh commands such as ls and cd (some path), however when I invoke a script which is written in GO on the board by typing the script name into the shell input I do not get a response back through the ssh connection established on the server side.

Example of what I send to the board to invoke the script: script argument1 argument 2 ... argumentN.

I know the script works as I intend (at least on the surface) because when I ssh into the odroid board like normal/directly, I am able to use the script as intended. The script outputs the correct commands on the shell through the use of fmt.Println([some string]).

However, when invoking the the script through the go ssh abstraction layer I do not get a response at all.

I have isolated the problem to the Stdoutpipe.Read() function on the server side in the code below. My program gets stick at this line.

I first thought this was a result of me not outputting the results on the shell correctly through the use of fmt.println so I tried the os.stdout.write() and os.exec.Command("echo something"), but these two attempts did not help.

Below is the main code snipits I used on the server side (where I am running the go ssh connection from) and the board side code (the code that I am running on the odroid to produce the desired response).

Server side code:

var serverTerminalInfo ServerTerminalInfo

err = json.Unmarshal(body, &serverTerminalInfo)
if err != nil {
    log.Fatal(err)
}

fmt.Println("ServerTerminal CMD:", serverTerminalInfo.CMD)
// Write a command to the remote shell
shellCMD := serverTerminalInfo.CMD + "\n"
fmt.Println(shellCMD)
io.WriteString(s.Stdinpipe, shellCMD) //Seems to have issues with multiple commands and server lnk. Need to see if the serverlnk files are avialable.

buf := make([]byte, 8192)
time.Sleep(2 * time.Second)
fmt.Println("Hold up here??")
**n, err := s.Stdoutpipe.Read(buf)**
fmt.Println("Sucessfully Read into buffer")

if err != nil && err != io.EOF {
    log.Fatalf("Failed to read command output: %s", err)
}

// Print the output

output := strings.TrimSpace(string(buf[:n]))
fmt.Println("Outputs should be produced?")
fmt.Println("Output Message:", output)

Board side code:

func transmitCommand(command string) {
        uartPortName := "/dev/ttyS1"

        // Configure UART communication settings.
        uartConfig := &serial.Config{
                Name:     uartPortName,
                Baud:     115200,
                StopBits: 1,
                Parity:   serial.ParityNone,
        }

        // Open the UART port with the specified configuration.
        p, err := serial.OpenPort(uartConfig)
        if err != nil {
                log.Fatalf("Failed to open UART port: %v", err)
        }
        defer p.Close()

        // Write data to the UART port.
        data := []byte(command)
        _, err = p.Write(data)
        _, err = p.Write([]byte("\r"))
        if err != nil {
                log.Fatalf("Failed to write data to UART port: %v", err)
        }
        //fmt.Printf("Wrote %d bytes to UART port.\n", n)

        buf := make([]byte, 8192)
        //var response []byte
        preVal := 0
        currentVal := 1
        time.Sleep(1 * time.Second)
        // Check if the buffer size is changing
        for preVal < currentVal {
                preVal = currentVal
                currentVal = len(buf)
                time.Sleep(100*time.Millisecond)
        } 
        //for {
        _, err = p.Read(buf)
        if err != nil {

log.Fatal(err)
        }
        fmt.Printf(string(buf[:len(buf)])+ "\n")

                //response = append(response, buf[:n]...)

                // Break the loop if a newline character is received.
                //if bytes.Contains(response, []byte("\n")) {
                        //time.Sleep(1*time.Second)
                        //fmt.Printf(string(response[:len(response)])+ "\n")
                        //for _, letter := range response {
                           //fmt.Println(string(letter))        
                        //}

                        //break
                //}
        
}

func main() {
        //app := "echo"
        //arg := "the GO Function is being executed"
        cmd := exec.Command("echo The go program is working")
        cmd.Run()
        //os.Stdout.Write([]byte("The GO Function is being executed"))
        if len(os.Args) < 2 {
                //fmt.Println("Not enough arguments present")
                //os.Exit(1)
                transmitCommand("")
                //transmitCommand("\r")
        }else{
        command := strings.Join(os.Args[1:], " ")

        fmt.Println("echoing the command:", command)
        transmitCommand(command)
        }
}

Any insight on what I can explore to solve this would be much appreciated.

Thank you all.

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. – Community May 08 '23 at 06:22

0 Answers0