Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Writing commands to linux bash
QtWS25 Last Chance

Writing commands to linux bash

Scheduled Pinned Locked Moved Solved General and Desktop
21 Posts 5 Posters 5.4k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J.HilkJ J.Hilk

    @devDawg
    Pressing the "Stop Button" in QtCreator is not the correct way to close your application!

    Thats a forcefull termination and may result in unexprected behaviour. For example not all destructors are called. On unix systems for example QSharedMemorys are not correctly released and remain active even after "Closing" the App via that method.

    I would suggest a proper function that calls
    QApplication::quit in your program, wenn you want to close it.

    devDawgD Offline
    devDawgD Offline
    devDawg
    wrote on last edited by devDawg
    #10

    @J.Hilk Duly noted, thank you. To add on to that , does pressing the red square emit a signal, so I could then connect that signal with QApplication::quit() ?

    The main issue that I'm trying to tackle right now, however, is unrelated to this. I have managed to write commands to my intended serial console, but they are not taking any effect, even when I end the command with \n or \r\n. Even if I write the command from pressing a button on my touchscreen GUI, then press Enter on my keyboard to submit the command, the serial console doesn't do anything (almost as if it hasn't detected any typing from the user, or something?)

    I would love to be able to solve this problem, please suggest any ideas you may have!

    EDIT: For configuring my serial communication, is it necessary to incorporate stop/start bits to notify the serial port that I am trying to submit a command?

    Current code that is not working:

    QSerialPortInfo *thing = new QSerialPortInfo();
    QList<QSerialPortInfo> ports = thing->availablePorts();
    
    
    QSerialPort *port = new QSerialPort(ports.at(0),this);
    port->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
    port->setDataBits(QSerialPort::Data8);
    port->setParity(QSerialPort::NoParity);
    port->setStopBits(QSerialPort::OneStop);
    port->setFlowControl(QSerialPort::NoFlowControl);
    port->open(QSerialPort::ReadWrite);
    port->setDataTerminalReady(true);
    port->write("reboot\r\n");
    //port->write("reboot\n");
    //port->write("reboot\r");
    //port->write("reboot");
    bool bytes = port->waitForBytesWritten(3000);
    qDebug() << "written: " << bytes;
    qDebug() << "flushed: " << port->flush();
    port->readAll();
    
    port->close();
    

    This code is inside of a slot that gets called when I press a quit button that I've instantiated on the touchscreen.

    When I press the button, I see the text getting written in the console; it just does nothing.

    Here is a picture of the serial console to give you more context:
    0_1530796326440_console.png

    PS: I know I shouldn't be using waitForBytesWritten, as it was previously pointed out.. I just didn't care to change that portion of code, as I did not think it was related to my current issue.

    Anything worthwhile is never achieved easily.

    JonBJ 1 Reply Last reply
    0
    • devDawgD devDawg

      @J.Hilk Duly noted, thank you. To add on to that , does pressing the red square emit a signal, so I could then connect that signal with QApplication::quit() ?

      The main issue that I'm trying to tackle right now, however, is unrelated to this. I have managed to write commands to my intended serial console, but they are not taking any effect, even when I end the command with \n or \r\n. Even if I write the command from pressing a button on my touchscreen GUI, then press Enter on my keyboard to submit the command, the serial console doesn't do anything (almost as if it hasn't detected any typing from the user, or something?)

      I would love to be able to solve this problem, please suggest any ideas you may have!

      EDIT: For configuring my serial communication, is it necessary to incorporate stop/start bits to notify the serial port that I am trying to submit a command?

      Current code that is not working:

      QSerialPortInfo *thing = new QSerialPortInfo();
      QList<QSerialPortInfo> ports = thing->availablePorts();
      
      
      QSerialPort *port = new QSerialPort(ports.at(0),this);
      port->setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);
      port->setDataBits(QSerialPort::Data8);
      port->setParity(QSerialPort::NoParity);
      port->setStopBits(QSerialPort::OneStop);
      port->setFlowControl(QSerialPort::NoFlowControl);
      port->open(QSerialPort::ReadWrite);
      port->setDataTerminalReady(true);
      port->write("reboot\r\n");
      //port->write("reboot\n");
      //port->write("reboot\r");
      //port->write("reboot");
      bool bytes = port->waitForBytesWritten(3000);
      qDebug() << "written: " << bytes;
      qDebug() << "flushed: " << port->flush();
      port->readAll();
      
      port->close();
      

      This code is inside of a slot that gets called when I press a quit button that I've instantiated on the touchscreen.

      When I press the button, I see the text getting written in the console; it just does nothing.

      Here is a picture of the serial console to give you more context:
      0_1530796326440_console.png

      PS: I know I shouldn't be using waitForBytesWritten, as it was previously pointed out.. I just didn't care to change that portion of code, as I did not think it was related to my current issue.

      JonBJ Offline
      JonBJ Offline
      JonB
      wrote on last edited by JonB
      #11

      @devDawg
      Excuse my coming late to the party. I know nothing about "serial consoles" but (I think) I do know about terminals & shells.

      I don't get what's going on here, or what you're trying to achieve. From what I can see you are writing characters into some kind of terminal window, but you haven't got a shell (bash) which is attempting to take what you're typing/sending and treat it as an interactive command on stdin to execute. I don't think there's anything here that matters about signals/slots or CR/LFs.

      Would you care to explain what you're actually trying to achieve, because I don't get it? And initially at least you said nothing about serial ports and didn't have any serial port code, does your question/do I need to understand anything about this serial port stuff, because I might be able to help better if that's not involved?

      Initially you seemed to just ask:

      All i want to do is run a linux bash command from inside of my Qt program with QProcess.

      If all you wanted to do was execute reboot you could just do so without any bash or /dev/ttyS0? That would run reboot on the machine where your Qt app is running, which is all your question seems to ask for.

      Now I'm wondering if /dev/ttyS0 is some serial terminal which is already running a shell, which you want to ask to do a reboot?? I'm lost!

      devDawgD 1 Reply Last reply
      0
      • JonBJ JonB

        @devDawg
        Excuse my coming late to the party. I know nothing about "serial consoles" but (I think) I do know about terminals & shells.

        I don't get what's going on here, or what you're trying to achieve. From what I can see you are writing characters into some kind of terminal window, but you haven't got a shell (bash) which is attempting to take what you're typing/sending and treat it as an interactive command on stdin to execute. I don't think there's anything here that matters about signals/slots or CR/LFs.

        Would you care to explain what you're actually trying to achieve, because I don't get it? And initially at least you said nothing about serial ports and didn't have any serial port code, does your question/do I need to understand anything about this serial port stuff, because I might be able to help better if that's not involved?

        Initially you seemed to just ask:

        All i want to do is run a linux bash command from inside of my Qt program with QProcess.

        If all you wanted to do was execute reboot you could just do so without any bash or /dev/ttyS0? That would run reboot on the machine where your Qt app is running, which is all your question seems to ask for.

        Now I'm wondering if /dev/ttyS0 is some serial terminal which is already running a shell, which you want to ask to do a reboot?? I'm lost!

        devDawgD Offline
        devDawgD Offline
        devDawg
        wrote on last edited by devDawg
        #12

        @JonB So from my primitive understanding, opening up a serial console provides access to the bash of the serially connected device.

        I've got a real-time data application that I am building for a Grayhill 3D70 touchscreen tablet. At this moment, I send commands to this device by opening a serial connection on PuTTY.

        What I'm trying to achieve: upon closing my application or pressing an on-screen 'quit' button, I would like to send the command 'reboot' to my device console to reboot, as this is a necessary operation to run an application after closing a previous one on this particular hardware.

        The reason I said nothing about serial ports initially is because I was trying to achieve this by echoing a command from the Linux bash within my virtual machine (echo 'reboot' > /dev/ttyS0), upon realizing that I was overcomplicating things.

        I'm sorry for being confusing. All i want is for my Linux device to 'reboot' upon app closure!

        If all you wanted to do was execute reboot you could just do so without any bash or /dev/ttyS0? That would run reboot on the machine where your Qt app is running, which is all your question seems to ask for.

        How would I go about doing this?? I would love to know!

        Now I'm wondering if /dev/ttyS0 is some serial terminal which is already running a shell, which you want to ask to do a reboot?? I'm lost!

        You are mostly correct on that. The device does not provide me access to its terminal, so I have to open up a serial console in a virtual machine to talk to its shell instead.

        Anything worthwhile is never achieved easily.

        JonBJ 1 Reply Last reply
        0
        • devDawgD devDawg

          @JonB So from my primitive understanding, opening up a serial console provides access to the bash of the serially connected device.

          I've got a real-time data application that I am building for a Grayhill 3D70 touchscreen tablet. At this moment, I send commands to this device by opening a serial connection on PuTTY.

          What I'm trying to achieve: upon closing my application or pressing an on-screen 'quit' button, I would like to send the command 'reboot' to my device console to reboot, as this is a necessary operation to run an application after closing a previous one on this particular hardware.

          The reason I said nothing about serial ports initially is because I was trying to achieve this by echoing a command from the Linux bash within my virtual machine (echo 'reboot' > /dev/ttyS0), upon realizing that I was overcomplicating things.

          I'm sorry for being confusing. All i want is for my Linux device to 'reboot' upon app closure!

          If all you wanted to do was execute reboot you could just do so without any bash or /dev/ttyS0? That would run reboot on the machine where your Qt app is running, which is all your question seems to ask for.

          How would I go about doing this?? I would love to know!

          Now I'm wondering if /dev/ttyS0 is some serial terminal which is already running a shell, which you want to ask to do a reboot?? I'm lost!

          You are mostly correct on that. The device does not provide me access to its terminal, so I have to open up a serial console in a virtual machine to talk to its shell instead.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #13

          @devDawg
          OK, at least I understand better now! As you say, your question has nothing to do with the initial question about QProcess. And you don't want to run anything from within your Qt app, you want it to get the serial-port-bash-console to receive some characters as a command to execute.

          So from my primitive understanding, opening up a serial console provides access to the bash of the serially connected device.

          So the serial device is there already running a bash, sitting waiting for a new command to arrive? (E.g. You don't have to log in now, just send it a command?) You have tested this outside of any Qt app? And you don't happen to have non-Qt code which does what you are trying to achieve in Qt?

          devDawgD 1 Reply Last reply
          0
          • JonBJ JonB

            @devDawg
            OK, at least I understand better now! As you say, your question has nothing to do with the initial question about QProcess. And you don't want to run anything from within your Qt app, you want it to get the serial-port-bash-console to receive some characters as a command to execute.

            So from my primitive understanding, opening up a serial console provides access to the bash of the serially connected device.

            So the serial device is there already running a bash, sitting waiting for a new command to arrive? (E.g. You don't have to log in now, just send it a command?) You have tested this outside of any Qt app? And you don't happen to have non-Qt code which does what you are trying to achieve in Qt?

            devDawgD Offline
            devDawgD Offline
            devDawg
            wrote on last edited by
            #14

            @JonB

            So the serial device is there already running a bash, sitting waiting for a new command to arrive? (E.g. You don't have to log in now, just send it a command?)

            I have a serial bash on my virtual machine that is connected to the device. Typing the reboot command manually does exactly what it's supposed to; I'm just tired of writing this command out every time. I would like it to auto-reboot upon closure.

            You have tested this outside of any Qt app?

            Yes.. The serial console accepts my reboot command when I type it in manually.

            And you don't happen to have non-Qt code which does what you are trying to achieve in Qt?

            While I have been looking, I have yet to find a really good example online. It is difficult to determine what exactly I should even be searching to get relevant results. Currently looking for similar issues.

            Anything worthwhile is never achieved easily.

            JonBJ 1 Reply Last reply
            0
            • devDawgD devDawg

              @JonB

              So the serial device is there already running a bash, sitting waiting for a new command to arrive? (E.g. You don't have to log in now, just send it a command?)

              I have a serial bash on my virtual machine that is connected to the device. Typing the reboot command manually does exactly what it's supposed to; I'm just tired of writing this command out every time. I would like it to auto-reboot upon closure.

              You have tested this outside of any Qt app?

              Yes.. The serial console accepts my reboot command when I type it in manually.

              And you don't happen to have non-Qt code which does what you are trying to achieve in Qt?

              While I have been looking, I have yet to find a really good example online. It is difficult to determine what exactly I should even be searching to get relevant results. Currently looking for similar issues.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #15

              @devDawg
              So forget Qt for now, can you provide a shell script (on your controlling Linux box) which does whatever to send the reboot to the serial port console and have it execute it?

              devDawgD 1 Reply Last reply
              0
              • JonBJ JonB

                @devDawg
                So forget Qt for now, can you provide a shell script (on your controlling Linux box) which does whatever to send the reboot to the serial port console and have it execute it?

                devDawgD Offline
                devDawgD Offline
                devDawg
                wrote on last edited by
                #16

                @JonB

                rebootscript.sh:

                #!/bin/bash
                echo 'reboot' > /dev/ttyS0
                
                

                I tested this by entering the command ". rebootscript.sh" when inside of its directory. It worked as expected.

                Anything worthwhile is never achieved easily.

                JonBJ 2 Replies Last reply
                0
                • devDawgD devDawg

                  @JonB

                  rebootscript.sh:

                  #!/bin/bash
                  echo 'reboot' > /dev/ttyS0
                  
                  

                  I tested this by entering the command ". rebootscript.sh" when inside of its directory. It worked as expected.

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #17

                  @devDawg
                  Oh! Now I understand that bit!

                  So we would indeed have thought that at least one of the attempts you show in your code, with the various ends-of-line, would indeed have achieved same....

                  To be same as script, you could open port only for write instead of r/w, but I doubt that would make a difference? Meanwhile does your existing port->readAll() return some kind of message?

                  To try to get it working just as a shell command, let's return to your very original attempt. Try:

                  proc->start("/bin/bash", QStringList() << "-c" << "echo 'reboot' > /dev/ttyS0");
                  

                  (and no proc->write()).

                  ?

                  (If you're prepared to make chmod +x rebootscript.sh you can also then try just proc->start("./rebootscript.sh").)

                  devDawgD 1 Reply Last reply
                  2
                  • JonBJ JonB

                    @devDawg
                    Oh! Now I understand that bit!

                    So we would indeed have thought that at least one of the attempts you show in your code, with the various ends-of-line, would indeed have achieved same....

                    To be same as script, you could open port only for write instead of r/w, but I doubt that would make a difference? Meanwhile does your existing port->readAll() return some kind of message?

                    To try to get it working just as a shell command, let's return to your very original attempt. Try:

                    proc->start("/bin/bash", QStringList() << "-c" << "echo 'reboot' > /dev/ttyS0");
                    

                    (and no proc->write()).

                    ?

                    (If you're prepared to make chmod +x rebootscript.sh you can also then try just proc->start("./rebootscript.sh").)

                    devDawgD Offline
                    devDawgD Offline
                    devDawg
                    wrote on last edited by
                    #18

                    @JonB Holy moly.. It worked. Why the extra "-c" argument? Is this to denote console?

                    Anything worthwhile is never achieved easily.

                    JonBJ 1 Reply Last reply
                    0
                    • devDawgD devDawg

                      @JonB

                      rebootscript.sh:

                      #!/bin/bash
                      echo 'reboot' > /dev/ttyS0
                      
                      

                      I tested this by entering the command ". rebootscript.sh" when inside of its directory. It worked as expected.

                      JonBJ Offline
                      JonBJ Offline
                      JonB
                      wrote on last edited by
                      #19

                      @devDawg
                      Meanwhile, returning the /dev/ttyS0 direct accessing.

                      @SGaist wrote:

                      Or since you are using a serial port, why not QSerialPort ?

                      Now beware, because almost always he is right and I am wrong(!), but I think this took us down a garden path. We only want to emulate echo 'reboot' > /dev/ttyS0. Now when bash does this line (I'm pretty sure) it does not do anything about looking to see that this is a serial port device and opening it with any kind of serial port code like your code attempted. It just passes /dev/ttyS0 to the standard Linux open(), and the device handler takes care of the serial-port-ness. So I would have thought you'd just want to pass that to plain old QFile and open for write.

                      1 Reply Last reply
                      0
                      • devDawgD devDawg

                        @JonB Holy moly.. It worked. Why the extra "-c" argument? Is this to denote console?

                        JonBJ Offline
                        JonBJ Offline
                        JonB
                        wrote on last edited by JonB
                        #20

                        @devDawg said in Writing commands to linux bash:

                        @JonB Holy moly.. It worked. Why the extra "-c" argument? Is this to denote console?

                        That's why UNIX provides man bash :)

                        The simplest way to get any of the shells to execute a simple command is:

                        /bin/bash -c "the command as a single argument"
                        

                        The -c says that a single argument follows of the entire command to be executed. Nothing to do with console.

                        Your original code did not pass that, and instead tried to run a bash without that argument, and present the command to be executed on the shell's stdin (same as -s argument). I am unsure why that did not in fact work, but using -c is preferable in any case.

                        It's good that this works now. But still a bit of overkill just to get a string sent to a device. I do think you should retry the "file" approach, but just use QFile (make sure you close it at the end) on /dev/ttyS0 instead of all that serial port code.

                        devDawgD 1 Reply Last reply
                        3
                        • JonBJ JonB

                          @devDawg said in Writing commands to linux bash:

                          @JonB Holy moly.. It worked. Why the extra "-c" argument? Is this to denote console?

                          That's why UNIX provides man bash :)

                          The simplest way to get any of the shells to execute a simple command is:

                          /bin/bash -c "the command as a single argument"
                          

                          The -c says that a single argument follows of the entire command to be executed. Nothing to do with console.

                          Your original code did not pass that, and instead tried to run a bash without that argument, and present the command to be executed on the shell's stdin (same as -s argument). I am unsure why that did not in fact work, but using -c is preferable in any case.

                          It's good that this works now. But still a bit of overkill just to get a string sent to a device. I do think you should retry the "file" approach, but just use QFile (make sure you close it at the end) on /dev/ttyS0 instead of all that serial port code.

                          devDawgD Offline
                          devDawgD Offline
                          devDawg
                          wrote on last edited by
                          #21

                          @JonB You may think it is overkill, and you are probably right, but it accomplishes what I need. For the meantime, I will settle for this so I can focus on other tasks at hand.

                          I really appreciate your patience and willingness to help, thank you @JonB !

                          Anything worthwhile is never achieved easily.

                          1 Reply Last reply
                          1

                          • Login

                          • Login or register to search.
                          • First post
                            Last post
                          0
                          • Categories
                          • Recent
                          • Tags
                          • Popular
                          • Users
                          • Groups
                          • Search
                          • Get Qt Extensions
                          • Unsolved