In python IDLE it won't print the specified error message when using sys.exit('') but in cmd.exe it will. Why?
import sys
try:
print fail
except:
sys.exit("This is an example of an error message")
Your error message is printed to stderr which is not shown in IDLE because it's run in a subprocess (see this report of your observation and this related answer). So IDLE writes it on the terminal used to start IDLE.
The documentation states about the arguments of sys.exit:
Some systems have a convention for assigning specific meanings to
specific exit codes, but these are generally underdeveloped; Unix
programs generally use 2 for command line syntax errors and 1 for all
other kind of errors. If another type of object is passed, None is
equivalent to passing zero, and any other object is printed to stderr
and results in an exit code of 1. In particular, sys.exit("some error
message") is a quick way to exit a program when an error occurs.
So, the safest way is to only pass error codes and use an additional print (or calling a custom exit-function that gives the user an analysis of what happened).
Related
I have written a code in that at some point calls an external executable using the system command.
Here is how I do this:
First remove the output files of the external code.
boost::filesystem::remove("Results/CVground.bin");
boost::filesystem::remove("Results/CVground.BUD");
then write input files for the external code. The code is too long to paste here. It just writes few ascii files.
Then run the model. To make things even worse as you can see I'm calling a windows executable under linux using wine.
std::string sim_command = "/opt/wine-stable/bin/wine ";
sim_command.append(cvd.simulationExe()).append(" CVsimAqua.in >/dev/null");
int sys = system(sim_command.c_str());
Essentially the command I'm calling under system is the following
int sys = system("/opt/wine-stable/bin/wine Simulation3.02.exe CVsimAqua.in >/dev/null");
UPDATE:
Based on the suggestion I modified the above command so that it prints to a file as such
int sys = system("/opt/wine-stable/bin/wine Simulation3.02.exe CVsimAqua.in > log.dat");
This is usually takes a couple of minutes to complete.
Then I'm doing a check that the output files actually exists as follows:
if (!boost::filesystem::exists("Results/CVground.bin")) {
std::cout << "\t\tSys output from rank " << rank << " is " << sys << std::endl;
fun.clear();
fun.push_back(10000000);
fun.push_back(10000000);
boost::filesystem::current_path(main_dir);
return;
}
I have found that in some cases I do get the following print in my log file. The rank number is different in each run.
Sys output from rank 78 is 32512
What I don't understand is that the output of system is positive, which I believe it means that the system command was successful. Is there any way to capture more information from the system command?
UPDATE
After I changed the from /dev/null to log.dat I realized that when the system fails it doesn't even create the log.dat file, however I always check with system(NULL) that system is available before calling the system.
I have found extremely difficult to debug this because these errors occur only when I run the code on the cluster.
Is it possible that the system command returns before the execution code finishes? I have seen a definite NO answer to that question but I was wondering if things are getting trickier since I'm calling via wine.
Thank you
The system function returns the exit code from the command you run. By convention, processes return 0 on success and non-zero on failure. What a non-zero exit code means, depends on the application, wine in this case. If may be easier to debug if you don't redirect its output to /dev/null
There are some specific return values for when the system call itself fails: -1 is a process could not be created, and 127 if a shell could not be executed. See man 3 system for the details on those cases.
There is a cpp application where I want to read following type of compressed file-
file_name.gz
file_name.Z
file_name.tar.gz
For this purpose, I check the file extension and choose decompression technique accordingly. E.g. file_name.gz will be decompressed using "gunzip -C file_name.gz".
I want to get the FILE handle for decompressed file. I use popen() API for it. Now, there might be a case where gunzip/uncompress/tar fails while decompressing the file due to memory issues. How do I capture the failure in my CPP application. There is way to check if popen failed or not. What about command passed to popen().
Please help. I tried to find it at various places but could not get satisfactory solution.
When a process terminates normally, it is expected to return the exit code of 0 (legally, EXIT_SUCCESS) to the parent. Otherwise, in the case of a crash or any other abnormal termination, a non-zero value is expected to be returned. You can obtain the exit code by calling pclose(). If the code is 0, the child process most probably terminated successfully.
Let's assume I am running a unix command using system("foocmd param1") on c++.
If foocmd returns "Invalid argument" back to the terminal via stderr, then how do I get my c++ code to know whether foocmd failed?
Here is my attempted solution:
My assumption is that I should check whether anything got returned to stderr by calling the command.
To do that, I tried switching over to popen. Currently, this is the way I check. I first output my stderr into a file.
sprintf(cmd, "foocmd param1 2>temp.txt");
system(cmd);
Then I check if temp.txt is empty or not.
But there has to be a better way. Can anyone lend me a hand?
The usual way is to examine the return value of system():
If it's zero, the command executed successfully and exited with a status of 0.
If it's negative, there was a problem with system() itself, and you can't assume anything.
If it's positive, then you can use WEXITSTATUS() and related macros to find out how the process exited.
See the system(3) man page for the full details.
Most of the time, you are only interested in whether the command says it succeeded:
if (!system(cmd)) {
syslog(LOG_WARNING, "Command \"%s\" failed", cmd);
/* maybe some more error handling here */
goto err_return;
}
I compile a fortran 77 code using gfortran and get the following error:
10 open (23,file=outfile,status='old',access='append',err=10)
1
Warning: Branch at (1) may result in an infinite loop
This happens several times.
One of the output files looks like the following:
^L6a10È <90> ) &<9b>LÓLÓLÕ<91><90> <90> <90> È <8e><9b>LÓLÓLÕ<93>2
!MERCURY ¢¤õ/!ô<8a><8a><90> ÿ<90> ÿ<90> ÿÌÖÏ©ü}M<91>
"VENUS «}>±{©±<8b><90> ÿ<90> ÿ<90> ÿʺ93¿<8d>d<91>
However, it should just look like a table of text.
Any ideas?
Your line of code
10 open (23,file=outfile,status='old',access='append',err=10)
specifies that the open statement should transfer control to itself (label 10) in case an error is encountered, so any error could trigger an infinite loop. It also suppresses the output of error messages. If you want to just check for an error status, I would suggest using the iostat and/or iomsg (Fortran 2003) arguments:
open (23, file=outfile, status='old', access='append', iostat=ios, iomsg=str)
Here ios is an integer that will be zero if no errors occur and nonzero otherwise, and str is a character variable that will record the corresponding error message.
The err= argument in your open statement specifies a statement label to branch to should the open fail for some reason. Your code specifies a branch to the line labelled 10 which happens to be the line containing the open statement. This is probably not a good idea; a better idea would be to branch to a line which deals gracefully with an error from the open statement.
The warning from gfortran is spot on.
As to the apparent garbage in your output file, without sight of the code you use to write the garbage (or what you think are pearls perhaps) it's very difficult to diagnose and fix that problem.
Does anyone know, how to capture ping's return value in c++? According to this link:
ping should return 0 on success, 1 on failure such as unknown host, illegal packet size, etc. and 2 On a unreachable host or network.
In C++ I called ping with the system (), e.g. int ret = system("ping 192.168.1.5");.
My problem is, that ret's value is 0 or 1. It will never 2! If I think correctly, this is because, this return value I get, is the system functions return value, not ping's. So how could i get ping's return vlaue?
Thanks in advance!
kampi
Edit:
Right now i use this system("ping 192.169.1.5 > ping_res.txt"); but i don't want to work with files (open, and read them), that's why i want to capture, th return value , if possible :)
If you are on Windows, it might be better to use IcmpSendEcho2 directly to implement the ping functionality in your application.
A simple solution would be pipe the output of ping to to a file and read it.
E.g.
system("ping 192.169.1.5 > ping_res.txt");
And read ping_res.txt to get the info you need.
From man 3 system on Linux:
RETURN VALUE
The value returned is -1 on error (e.g. fork(2) failed), and the return status of the command otherwise. This latter return status is in the format specified in wait(2).
Then from man 2 wait on Linux:
If status is not NULL, wait() and waitpid() store status information in the int to which it points. This integer can be inspected with the following macros (which take the integer itself as an argument, not a pointer to it, as is done in wait() and wait- pid()!):
WIFEXITED(status)
returns true if the child terminated normally, that is, by calling exit(3) or _exit(2), or by returning from main().
WEXITSTATUS(status)
returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should only be employed if WIFEXITED returned true.
From sys/wait.h on Linux:
# define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status))
From bits/waitstatus.h on Linux:
/* If WIFEXITED(STATUS), the low-order 8 bits of the status. */
#define __WEXITSTATUS(status) (((status) & 0xff00) >> 8)
In other words, you will wan to use these macros if you are using Linux. Are you using HP-UX? I notice you link to information for HP-UX. If so, what does your man 3 system page say?
Also, keep in mind that system invokes "sh -c command" and you will receive the return value of sh:
EXIT STATUS
The following exit values shall be returned:
0 The script to be executed consisted solely of zero or more blank lines or comments, or both.
1-125 A non-interactive shell detected a syntax, redirection, or variable assignment error.
127 A specified command_file could not be found by a non-interactive shell.
Otherwise, the shell shall return the exit status of the last command it invoked or attempted to invoke (see also the exit utility in Special Built-In Utilities).
What return value do you find if you attempt, e.g., system("exit 203");?
So you just want to know the return value: i.e. "0 on success, 1 on failure such as unknown host, illegal packet size, etc. and 2 On a unreachable host or network." I think using ping is an overkill in this case. Writing to file and reading from it is apparently a little bit ugly.
I think you should just try **open()**ing a connection to the host on port 7 (Echo). Then you would get the information that ping return value would tell you. If you further want to get response durations, you can measure it yourself by sending arbitrary data to the host on echo port. It would take some time to write the code but i think it's worth for flexibility and accuracy.