I have a python script that outputs to the console every 10 seconds or so.
I want to run that script from my c++ code, and keep it running to continue getting updates until I close my app. If I use popen, I can get the output line by line, without having to wait for the script to "finish", but I cannot kill it when I close my app now.
Is there a way to read the output of a script as it is spit out, keeping the script running until I close my qt app?
Thanks!
QProcess allows you to call a external process from code. The documentation includes information on how to close it within the program. Also you can use the read/write channels for communication.
There are some examples in the documentation and method descriptions, for getting started.
Related
I am designing a gui application using qt creator. In there if i press a button, values from a .csv file gets imported to an sqlite3 database table.
For doing this I have used the QProcess to launch a shell script that contains the commands for importing data.
void MainWindow::on_pushButton_clicked()
{
QProcess process;
process.startDetached("/bin/sh", QStringList()<< "/home/aj/myscript.sh");
}
and myscript.sh for importing is--
echo -e '.separator ","\n.import import_table.csv test_table' | sqlite3 testdatabase.db
the reason behind this approach is that dot-commands can not be integrated directly to the c++ gui program without creating custom parsing solutions.
Now, this approach (QProcess and shell script) works perfectly well for me. But one bottle neck is it does not offer any error-handling/identification.
For example if the import command stops midway during data retrieval or all the values in .csv are not imported I would not know the problem. Is there any way to know if problem has occurred during importing ??? (redirecting the message via QDebug???)
QProcess has a member function called exitCode() which oddly enough returns the exit code of the process.
http://qt-project.org/doc/qt-5/qprocess.html
Finding that answer required a 10-second search in google for the documentation...
I have to write a program that intercepts data from terminal and i have to parse it. After processing when the data, i have to parse it before it goes to stdout.
I can't use tee or commands like prog > file 2>&1 as the program is going to be interactive.
For example :
If the user types ls in the terminal i have to parse it then it should go operating system and then when I get the result after processing I ll have to again parse it before it's displayed in the terminal.
I did my research and I think I can achieve it through pseudo terminal interfaces ( pty ).
Please let me know if there is a better way to achieve it.
I am using cpp and bash and the platform is *nix.
Update:
I can also use libexpect from expect.
I am not sure what do you mean here - you mean interactive program as "working in another terminal communicating with user" or even displaying GUI?
How does it specify the terminal? It is probably important what is program layout here (which program starts which).
If your application uses GUI to communicate with user, then I would simply do it this way:
start bash with sdtin and stdout attached to pipes,
your program reads & writes to it's end's of those pipes, parses data, and reads/writes on it's own stdin&stdout - so it appears on it's terminal.
If you mean controlling different terminal than your application's, it gets though since system generally does not expect program operating on multiple terminals. I don't think it's possible to filter communication between terminal and already working application attached to it. Starting another process spawning another terminal might be an option - to have basically two terminals working in sync. But then you will have to synchronize both processes by some other means (named pipes, network connection or some other IPC).
If you provide more detail on your program I might provide more directed help.
PS Don't tell me that you are writing some terminal keylogger ')
EDIT:
Your program is probably GUI based then - what i would recommend would be something similar to answer linked by banuj.
Best option will probably be to create three pipes, then fork, and in child process assign corresponding ends of pipes to stdin, stdout and stderr. Then child process should exec into shell - probably bash, although I am not sure if other shells would sound better if read out loud ;) Main process will be able to read/write other ends of mentioned pipes, parsing both inputs and outputs to bash and programs it runs.
You could also exec directly to commands user specifies, but that forces you to take over tedious job of a shell - managing current directory, environment variables, job control and so on.
Using above method might however cause some trouble - some programs (usually in security related contexts - eg. su(do) asking for password) will try to bypass stdin/stdout anyway and read directly from terminal device. I am not sure what can you do in such case - programing your own terminal emulator would be an option, but I don't know if you want to go this deep into system programming for this.
If you want some code snippet's, if you don't know how to do above, just ask ;)
i am new to python and am trying to call a c++ function from python, I cam across this answer from Florian Bösch and found it really helpful, i did everything as in the link but i have a small problem which really surprised me, when i run the fooWrapper.py from command prompt it displays the result "hello" but when i run the program from idle by clicking run as module the python shell opens and displays nothing, only action is the cursor moves down as when you press enter. Is this normal or is this a problem???
I use python 2.7.3(32bits),with windows 7 and MInGW complier.
The problem is that IDLE redirects standard input and output, but your C++ function writes to the original standard output and thus IDLE will not show it. If you launch IDLE from a terminal you will see the C++'s output in the terminal.
It's a problem of IDLE, and I doubt that you can do something about it.
If you want to develop something bigger than a really small script you ought to use a different IDE.
I'm developing a chat server in C++. The programme is built and run from a terminal. As running in the terminal, I can write to this terminal normally using 'printf'. Some of the information written to this terminal are the alerts of new incoming connections, outgoing connections, etc.
Now I need to get the keyboard input so that admin can type commands to see the values of variables in the chat server. I intend to create a new thread and attach a new terminal to it. A suggestion is to call system("gnome-terminal"), but it requires a little delay with sleep(), doesn't seem to be a good choice because all the contents redirected to this gnome-terminal will be considered as bash commands. And I don't know how to attach the terminal opened by 'system'` command to the thread.
Any simple way to attach a terminal to created thread?
Maybe have a read of this on how to use pipes in Linux
http://linuxprograms.wordpress.com/tag/pipes/
As partially answered in this question: Avoid gnome-terminal close after script execution?
There is a good option like this:
(1) Use the main terminal for normal input/ouput.
(2) Create log file (log.file) before calling 'tail'
(3) Use 'tail' command for showing log contents (log files)
//c++ code
system("gnome-terminal -e \"bash -c 'tail -f log.file'\"");
(4) Append the content to 'log.file' to tell 'tail' to show it up.
I want to unzip a zipped folder on my Redhat machine.
To do this I send a bash script the string;
"unzip /usr/bin/Folder.gz"
This unzips the folder no problem, as in I get the general
inflating folderA/folderB/fileX
etc.
However, I want to hold the code at the unzip command, waiting until the unzipping is complete.
I have tried using
sleep(5)
but I don’t want to use this and just hope that it will always take less than five seconds especially this is would be inefficient for very small zipped files.
I have searched online but to no avail...
So my question is; what is a reliable way to stall a program until the unzipping is complete?
O/S: Redhat
Programming Language: C++
IDE: Eclipse
How do you run the bash script?
If you use the system() API it will start the program and then wait until the spawned process ends.
system() system is a call that is made up of 3 other system calls: execl(), wait() and fork(). Source.
Try:
unzip /usr/bin/Folder.gz &
wait $!
That will cause the shell to wait on the completion of the last process. The pid of the last executed command is stored in $!.
Not sure how this relates to C++, but if you want to do the same from code you can use the waitpid function.
Of course, if you want your program to block while unzip executes I'm a little confused as to what the exact problem is. Assuming you're using system or some equivalent to run unzip, it should block until the command completes.
I'm not really sure this is the best way, but it is reliable.
Now instead just sending the command to the bash why not send the output to some file.
unzip /usr/bin/Folder.gz > output.txt
Read the file in regular intervals from your C++ code (lets say 1 sec) once you find 100% or whatever the last line of the output should contain and then carry on with your code.
I don't know if this would be overkill or inefficent, but you could move the process of unzipping in to another thread, and halt your main thread until that thread is finished processing