I have this piece of code in my c++ project:
std::string run_command = "build/executable input.txt";
std::string copy_command = "cp output.txt output_1.txt;";
int status1= system(run_command.c_str());
int status2=system(copy_command.c_str());
It perfectly runs in my pc, but doesn't work in my laptop. Both system calls return -1, meaning that there is a problem in shell process creation. What do you think is the problem?
As reported by manual:
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). Thus, the exit code of the command
will be WEXITSTATUS(status). In case /bin/sh could not be executed,
the exit status will be that of a command that does exit(127).
So, path should be correct. Try to add some print debug in your scripts.
Maybe you are referring to resources or libraries that in your laptop does not exist.
try using ptrace and print errno (http://man7.org/linux/man-pages/man3/errno.3.html) to find the reason as to why system call failed. This is another resource to steer you on why the system call failed http://bytes.com/topic/c/answers/217348-get-system-error-message
P.S.
I'm not entirely confident in writing c++ systems programs but i build a shell in C and printing errno helps. I definitely recommend using ptrace as well as monitoring whether the OS has enough resource to allocate new processes.
Related
This question already has answers here:
How to get the exit code of program invoked by system call?
(3 answers)
Closed 5 years ago.
I have a requirement of developing a small dependency manager for a Qt based C++ application I am developing. This C++ application will be targeting Linux systems. So this is how it works. I execute a shell script through the system() function. In the shell script I check whether the required packages are installed, if not I exit the shell script with the status of the last executed command. My question is, how do we capture this in C++ and handle it? (I want to capture it so I can inform the user that some of the dependencies are not installed and seek user permission to install them)
C++ code :
system("./myscript.sh");
Shell code :
iwconfig
exit $?
I've tried this aproach earlier on:
in C++ :
int i = system("./myscript.sh");
if(i!=0)
QMessageBox::information(this, tr("test"), tr("program exited with exit code"+i));
But then I get the following error :
The inferior stopped because it received a signal from the operating system. Signal name : SIGSEGV Signal meaning : Segmentation fault
How to get it done??
Prototype of system command is:
int system(const char *command);
and it returns the exit code of the command, that it executed (the shell script in your example). So you have simply use:
int status = system("./myscript.sh");
I have a requirement of developing a small dependency manager for a Qt based C++ application I am developing.
You should consider instead making a proper package for your (or some common) distribution (e.g. some .deb file for Debian or Ubuntu), because package managers do this job (handing dependency management) better than you reasonably could.
The return code of system(3) is actually the status code given by waitpid(2). Read about exit status of bash and shells. So if the last command executed (by /bin/sh -c started by system(3)) crashed with a SIGSEGV (see signal(7)...) you could use WIFSIGNALED then WTERMSIG
I guess that some program run by your ./myscript.sh crashed badly.
You might consider using the shell trap builtin in your script to handle that.
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.
Well, I will put it plain and simple: I am a C++ pleb. Still trying to learn though.
My question is: is it possible to run a command though the terminal using system() command without letting the command be shown in the console/terminal?
Example:
system("sudo service sshd start") ;
Output: Sudo service sshd start
Where as I want:
system("sudo service sshd start") ;
output: (Blank)
Note: I am on linux.
The system standard library function starts up a subshell and executes the provided string as a command within that subshell. (Note that a subshell is simply a process running a shell interpreter; the particular shell interpreter invoked by system will depend on your system. No terminal emulator is used; at least, not on Unix or Unix-like systems.)
The system function does not reassign any file descriptors before starting the subshell, so the command executes with the current standard input, output and error assignments. Many commands will output to stdout and/or stderr, and those outputs will not be supressed by system.
If you want the command to execute silently, then you can redirect stdout and/or stderr in the command itself:
system("sudo service sshd start >>/dev/null 2>>/dev/null") ;
Of course, that will hide any error messages which might result from the command failing, so you should check the return value of system and provide your own error message (or log the information) if it is not 0.
This really has very little to do with the system call or the fact that you are triggering the subshell from within your own executable. The same command would have the same behaviour if typed directly into a shell.
I’ve produced a C++ program in Eclipse running on Redhat, which compiles and runs fine through Eclipse.
I thought that to run it separately to Eclipse you use the build artifact which is in the directory set via the project’s properties.
However this executable doesn’t run (I know it’s an executable as I’ve set it to be an executable via the project’s properties and it shows up as such via the ls command and the file explorer).
When attempting to run it using the executable’s name, I get the error:
bash: <filename>: command not found
When attempting to run it as a bash file:
<filename>: <filename>: cannot execute binary file
And when running it with "./" before the file name, nothing happens. Nothing new appears in the running processes and the terminal just goes to the next line as though I’d just pressed enter with no command.
Any help?
You've more or less figure out the first error yourself. when you just run <filename> , it is not in your PATH environment variable, so you get "command not found". You have to give a full or relative path when to the program in order to run it, even if you're in the same directory as the program - you run it with ./<filename>
When you do run your program, it appears to just exit as soon as you start it - we can't help much with that without knowing what the program does or see some code.
You can do some debugging, e.g. after the program just exits run echo $? to see if it exited with a particular exit value, or run your program using the strace tool to see what it does (or do it the usual way, insert printf debugging, or debug it with gdb)
if( system("tail -500 log.txt") == -1)
{
//Error calling tail.exe on log
//errno is a system macro that expands int returning
//the last error. strerror() converts the error to it's
//corresponding error message.
printf("Error calling tail.exe with system(): %s",strerror( errno ));
}
System() is calling Tail.exe with log.txt
All are in the same directory as the executable calling it.
Getting the error ENOENT- No such file or directory
Also, specified paths to everything, same error.
Any advice is appreciated, thank you.
From the docs on system() that you linked:
ENOENT
Command interpreter cannot be found.
So the problem isn't that it can't find tail.exe, the problem is that it can't find the command interpreter. This suggests that something larger is going wrong. We'll need more information to diagnose the real problem. Also from the same page:
The system function passes command to
the command interpreter, which
executes the string as an
operating-system command. system
refers to the COMSPEC and PATH
environment variables that locate the
command-interpreter file (the file
named CMD.EXE in Windows NT and
later). If command is NULL, the
function simply checks to see whether
the command interpreter exists.
This suggests a couple of avenues for investigation: What does system(NULL) return? And what are the values for the COMSPEC and PATH environment variables when your program runs?
You might try system("cmd tail -500 log.txt") - that's been necessary on some windows boxes.