Writing commands to linux bash
-
@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 anybash
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!@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 anybash
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.
-
@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 anybash
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.
@devDawg
OK, at least I understand better now! As you say, your question has nothing to do with the initial question aboutQProcess
. 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? -
@devDawg
OK, at least I understand better now! As you say, your question has nothing to do with the initial question aboutQProcess
. 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?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.
-
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.
-
@devDawg
So forget Qt for now, can you provide a shell script (on your controlling Linux box) which does whatever to send thereboot
to the serial port console and have it execute it? -
#!/bin/bash echo 'reboot' > /dev/ttyS0
I tested this by entering the command
". rebootscript.sh"
when inside of its directory. It worked as expected.@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 justproc->start("./rebootscript.sh")
.) -
@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 justproc->start("./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.@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 Linuxopen()
, 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 oldQFile
and open for write. -
@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. -
@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.