I was wondering if there is any way to read the output of a console command, from executing it in code. OK that's probably not the clearest way I could have put that, so let's have an example:
My project PingSweepr is, as the name implies, a simple network ping sweeper that uses the C++ system() command to automate ping sweeping with the Windows shell ping command.
The only problem is, there is no way to sort the results (btw, this would be used in more than just that program, in case you were wondering), which would involve parsing the command-line output of the ping program. So basically my question is: is there any way to read the output from the shell into the program? Maybe through a system message hook or something, or is it just not possible?
Thanks!
Have you tried looking at the popen function? This older question has some discussion:
Capturing stdout from a system() command optimally
Here is the answer: How to execute a command and get output of command within C++ using POSIX?
Related
I need to run this shell command in a C++ script:
"/usr/local/bin/mjpg_streamer -i "/usr/local/lib/input_uvc.so" -o "/usr/local/lib/output_http.so –w /usr/local/www" -b"
This command launches an application which broadcasts a video feed. When I execute this command via system() in C++ the application doesn't start properly.
I use:
system("/usr/local/bin/mjpg_streamer -i \"/usr/local/lib/input_uvc.so\" -o \"/usr/local/lib/output_http.so –w /usr/local/www\" -b");
When I try to access the video stream after I started it with the C++ application the webpage returns:
501: Not Implemented!
no www-folder configured
I can't expect you guys to give me an application related solution, but I'm wondering if there's a difference in the way commands from a C++ application using system() and commands directly entered in a terminal are executed.
EDIT: The application broadcasts the video stream on IP:8080. I access it by going to that IP in my browser. Usually it opens a webpage with the stream in it but when I execute the command with the C++ application I get that error.
Edit: The old idea of mis-placed quotes was wrong; I realize that -w is actually an option to output_http.so, so the whole shebang must be passed as a single parameter to the -o option, as shown here or here etc.
In that case, check file permissions etc. Does /usr/local/www exist? Is it possible that you are running the shell command from a root shell?
Hey, I have a book recommendation, too, "one of the best tech books ever published": Stevens' Advanced Programming in the Unix Environment. The guy knows -- sorry: knew -- what he was talking about.
I would avoid using the system(3) library function, or at the very least, check its returning error code. I don't understand why you are using " inside your command (I believe that in your particular case, you don't need them; but in general beware of code injection!). Read about globbing
You could use popen(3) to at least get the output of the command.
Even better, code yourself the running of the mjpg_streamer program using the fork(2) & execve(2) & waitpid(2) and other syscalls(2) (perhaps pipe(2), poll(2), dup2(2) etc...). Read Advanced Lnux Programming for more.
I have a program that executes various shell commands via system() and occasionally prints to cout. I want to redirect all output coming from system() calls to a log file so they don't clutter up the normal output. Can I do this without having to append > log to all my system commands?
Looks like you can use popen
Close the stdio file descriptors (0, 1, and 2) and re-open them on whatever output device you like.
Using system is just a bad idea, period. If you use fork and execve or posix_spawn, you can easily make the necessary redirections and avoid all sorts of vulnerabilities from shell quoting issues.
If you can use a library that wrap process call. It is hard to code from posix. I use boost.process, it works fine. you can simply tell the lib how you want the output to be redirected...
my2c
I have written a simple program that pings three sites and then reacts to whether they are reachable or not.
My question is: can I suppress system("ping ")'s output? I have written my code in C++ as I know that language the best. Currently the code opens the ping.exe running the system command. If I can prevent the output from showing up while it still pings that would be ideal.
I am eventually going to turn this program in a windows service that is why I would like to suppress both the command line console window as well as suppress the ping output. Thanks.
Try doing system("ping host > nul") (nul is windows equivalent of UNIX /dev/null).
Generally, if you're going to call another program but don't want it to act like std::system, you're going to need a platform-specific function like fork()/exec() on UNIX or CreateProcess() on Windows. These functions give you control over how the other program runs, for instance, that it not show output or not create a console window, etc.
You can use system command like below to suppress the output of ping command.
system("ping 100.100.100.100 > response.dat");
Above command pings IP address 100.100.100.100 and directs the output to a file called response.dat. In response.dat you can see the response of ping command.
Do system( "ping site.com >nul 2>nul" ); and check the value the shell returns.
if the ping succeeds, the shell will return 0, else it will return 1.
I would be more detailed, but Vis Studio is reinstalling itself. :)
There's also a way to hide the console window using the Win API to exec the command, but...
I do not remember the details.
Edit:
I'm still waiting for the MSVS install process, so... :)
Use CreateProcess with the DETACHED_PROCESS flag for the dwCreationFlags parameter to hide the console window.
After you call create process, you'll have to use WaitForSingleObject on the process handle to wait for the ping to complete. The last parameter to CreateProcess should have a pointer to process information that contains the process handle. (Assuming CreateProcess was successful) You have to wait for the command to complete. Once it's complete, you can use the process handle to get the return value, though I'm too time contstrained to tell you how to do that at this point.
When you get over to Windows and call CreateProcess(), be sure to set:
lpStartupInfo->wShowWindow = SW_HIDE;
This will ensure that any windows created by the new process are hidden.
Using the DETACHED_PROCESS flag will prevent the new process from inheriting your application's console, but that does not prevent the new process from creating a new console. Not sure what ping would do, but best to remove all doubt by using SW_HIDE.
You could also use this way, this will return the output in a file and doesn't show up a console windows and freezes the main application which is really usefull.
At first you need to include the Windows header using;
#include <Windows.h>
then send a ping command and write the output into a file like this;
WinExec("ping google.com > file.dat", SW_HIDE);
This will send a ping command to google.com and writes the output to the file 'file.dat' in the directory of your current running program. So you could change file.dat to any file or filepath you want and of course you could change the ping command. The > character means that the output of the command needs to be wrote in the file path behind it.
If you want to show the console window and freeze the application while running the ping command you need to use the following line of code instead of the WindExec() code;
system("ping google.com > file.dat");
I'm working on a Command Line app to help me on launchd tasks to know if a task is running by returning a BOOL, the problem comes when i need to do a command line and obtain the output for further parsing.
i'm coding it in C/C++ so i can't use NSTask for it, any ideas on how to achieve the goal?
The Command
sudo launchctl list -x [job_label]
If i use system(), i'm unable to get the output so in further research I came with popen(), but no success there.
Thanks in advance.
You'll want to create a pipe from which you can read the output of the program. This will involve using pipe, fork, exec*, and maybe even dup. There's a good tutorial on the linux documentation project.
You can do it the home-brew way with pipe(), fork(), and the exec*() family of functions, or you could use popen() if its constraints meet your requirements.
I try to call a program (ncbi blast, for those who need to know) from my code, via calling the command in a system() call.
If I execute the string directly in the shell, it works as intended, but if I try the same string via system(), the program returns much faster, without the intended results. The output file is created, but the file size is 0. The returned error code is also 0. I even tried appending "> output.log 2> error.log" but these files are not created.
I guess it has something to do with environment variables or the path...
The output file name is given via -o command line parameter, not output redirection.
I read something about the popen command being possibly better suited for my use-case, but I can not find it, which library is that from?
The most usual cause of such problems is incorrect environment variable setting in ones ~/.bashrc.
You should be able to see what ncbi is unhappy about by executing
$SHELL -c '<exact string you pass to system()>'
Another common way to debug this is with strace. Execute:
strace -fo /tmp/strace.out ./myProgram
and look in /tmp/strace.out for clues.
Is there any reason that you do not want to fork and exec? This is a common idiom for executing one process from another.
popen is in the standard C library
See the man page
Some quick questions:
How do you execute in in the shell?
How do you execute in the system command?
What is the value returned by system?
Exact copy and paste from you terminal is preferable then an English description.