How can I catch exception on bash file exit unnormally? - c++

Here I get a bash file b.sh:
#!/bin/sh
if [ ! -f somefile.txt ]; then
..................
fi
in the bash file ,I try to check whether somefile called "somefile.txt" exist, if not, I would consider it as an error and exit.
And I run this bash file in c++:
::system("sh b.sh")
What should I fill in the "..............." in that bash file and what should I do in c++ code to catch exception when the "somefile.txt" is not found.

Put:
exit 1
in the script -- by convention, any non-zero exit code is considered failure.
In the C++ code, system() returns the termination status of the command. See the documentation of wait() for details of interpreting this, or you can just check if it's non-zero if you want to know if there was any error.

Related

What is the purpose of echo command after executing a program?

Why do we exit issuing an echo command while executing a program?
As far as I know, the echo command for console windows is:
$ echo $
And for windows is:
$ echo %ERRORLEVEL%
When the child process ends, the set variable ERRORLEVEL contains an integer returned by it. ERRORLEVEL is measured 0 if the process was successful (i.e. return 0). OTOH, 1 or greater if the process encountered an error.
However, I don't know what do you exactly mean by:
echo command after executing a program
I never ran this command neither I've seen anywhere.

How to make LLDB quit on success, wait on failure?

This is the Clang version of:
Make gdb quit automatically on successful termination?
How to have gdb exit if program succeeds, break if program crashes?
Running my application many times, programmatically, over a large number of possible inputs, I've occasionally encountered a segmentation fault.
I'd like each test invocation to be run under lldb so that I can get a backtrace for further debugging. If an invocation exits without a crash, I'd like lldb to automatically quit so that the test harness progresses to the next iteration. This way I can set the whole thing off over lunchtime and only have the suite interrupted when something crashes.
Bonus points for having lldb auto-quit in all cases, but first print a backtrace if the program crashed.
I'm currently able to automate at least the initial run command:
lldb -o run -f $CMD -- $ARGS
I'm having difficulty finding an online command reference but it looks like the -batch command line option will get you the basic "exit on success/prompt on fail" behaviour.
For a backtrace and auto-quit on failure I think you need the --source-on-crash option...
-K <filename>
--source-on-crash <filename>
When in batch mode, tells the debugger to source this file of lldb
commands if the target crashes.
So, create the command file with something like...
echo -e 'bt\nquit' > lldb.batch
and then invoke as...
lldb --batch -K lldb.batch -o run -f $CMD -- $ARGS

Procedure for using gdb to examine output and error messages returned by a called program

I've got a program written in C++ which has a function that looks similar to this:
std::string cmd = "curl -s http://x.x.x.x/latest/meta-data/public-hostname";
std::vector<std::string> output;
runCmd(cmd, output);
If the curl command fails the program silently ignores it. I need to be able to examine what's happening when the program gets to this point: I'd like to look at the output generated by curl, including error message and return code.
How do I do this with gdb? Please walk me through the steps of running the program with gdb so I can see what's happening with curl. It's a fairly large program. I am only interested in this particular function call, I want to ignore everything else up to that point.
i should note that I don't have the environment to compile the code. All I've got is the binary.
Not sure gdb will help you much as you spawn a sub process.
I would suggest changing the code to
std::string cmd = "curl -s http://x.x.x.x/latest/meta-data/public-hostname 2>/tmp/error | tee /tmp/output";
so that /tmp/erro and /tmp/output gives you what happened;
EDIT:
as compilation os not possible, you may use this trick:
create a script named curl containing:
#!/bin/bash
/usr/bin/curl $# 2>/tmp/error | tee /tmp/output
(don't forget to change permission to +x)
then, when executing your program just do:
PATH=.:$PATH ./yout_binary
assuming your script is in .
then the program will use your 'fake' curl
I would use strace for this task, rather then gdb:
strace -f -s 1024 -o log ./program
Here -f mean to trace child processes as well. You need it because this line of code runCmd(cmd, output); most likely does fork() to run child process.
-s 1024 specifies maximum string size to print. By default it is 32 which is often too short.
Once you save the output to log file, you should easealy find something like curl -s in it. This is where the child process starts. You can see what it writes to stderr or stdout in lines like write(2, "... or write(1, ".... At the end of the process execution you will see it's exit code, for example 1 exit code:
exit_group(1) = ?

Program Runs Even Though I Return -1?

I am running this very simple c++ code:
int main()
{
return -1;
}
But when I compile it with g++ and run it (on ubuntu 14.04) it goes through and I get no errors. The book that I am reading, "C++ Primer" says that I should receive an error, so I was wondering if someone could show me what I am doing wrong.
Your program runs normally, then returns a status of -1 to the environment. If you don't look at that status, you're not going to see any indication of an error.
If you're running from the bash shell, you can do something like:
if ./my_program ; then
echo Success
else
echo Failure
fi
or, on one line:
if ./my_program ; then echo Success ; else echo Failure ; fi
or, if you want to be obscure:
./my_program && echo Success || echo Failure
More simply:
./my_program
echo $?
Incidentally, returning a status of -1 is not a portable way to indicate failure. I suggest adding #include <cstdlib> to the top of your program and using return EXIT_FAILURE;. (The value of EXIT_FAILURE is typically 1, but it will be whatever it needs to be to denote failure on the system you're using.)
The code that you've written here is perfectly legal C++. The program runs and then signals an exit code of -1. On some operating systems, if a program terminates with a nonzero exit code, the OS will report an error to the user indicating that something weird happened. On Ubuntu, though, programs that terminate with nonzero exit codes don't trigger an explicit error message, so what you're seeing is the expected behavior.
The return value of main is what's called an exit code. If you run your program from a shell (such as bash on a Unix system or the CMD on Windows), you can examine the exit code. By convention, nonzero exit codes usually imply that something erroneous happened. For instance, your g++ compiler outputs a nonzero exit code if there's a compile error and 0 if everything goes correctly.
Since you said you're on Ubuntu, I assume you're using either bash or dash to run this program. Try running the program and then do echo $? after running the program. You should see the exit code your program returned.

Using grep to match one digit with TCL

The file that I want to grep contains many lines.
I want to grep lines which contain only 1 digit: "0" or "1".
I used this command:
exec grep -e "^\[0-1\]{1}$" file
But I got:
child process exited abnormally
What's wrong with RegExp of grep?
The most common issue when running grep as a Tcl subprocess is that it exits with a non-zero error code when it doesn't find anything at all. This always causes Tcl to throw an exception. The simplest workaround is perhaps this:
exec /bin/sh -c {grep -e '^[0-1]{1}$'; true} < file
Note that we are feeding in the file using a redirection here; this means that it is not necessary to strip the name of the file from the results.