4

For example, I have a script ./helloworld.sh

I would like to call it in C++, how do I do that? Which library can be used?

Rich
  • 5,603
  • 9
  • 39
  • 61
skydoor
  • 25,218
  • 52
  • 147
  • 201

6 Answers6

10

try

system("./helloworld.sh");
bits
  • 8,110
  • 8
  • 46
  • 55
5

If you just want to run it (and nothing else)

system("./helloworld.sh");

If you need to get the stdin/stdout then you need to use popen()

FILE*  f = popen("./helloworld.sh","r");
Martin York
  • 257,169
  • 86
  • 333
  • 562
3

try system().

KLee1
  • 6,080
  • 4
  • 30
  • 41
1

In C there are also the execxxx functions from unistd.h. They have a big advantage over the simple system as you can specify environment variables for your process to run in among other levels of control for the arguments management.

jdehaan
  • 19,700
  • 6
  • 57
  • 97
  • 4
    What would he be willing to do with an bash sh file under Windows? :-) – jdehaan Jul 07 '10 at 21:35
  • 1
    You would also lose control of the c++ program wouldn't you? If I remember, exec never returns. – KLee1 Jul 07 '10 at 21:35
  • @KLee1, you are absolutely right, the process is replaced... Not such a good idea in cases you want to control the stuff after all. I forgot that. – jdehaan Jul 07 '10 at 21:40
  • IMO system is the way to go, since its platform independent, and specifying environment variables isnt a problem at all, since you can set the desired environment variables beforehand with more `system` calls (i am thinking of set/export). Btw @jdehaan, MSYS supports sh files. – smerlin Jul 07 '10 at 22:48
1

There are at least two possible ways. (I suppose you are asking about Unix-like systems when using shell scripts).

The first one is very simple, but is blocking (it returns after the command has been completed):

/* Example in pure C++ */
#include <cstdlib>
int ret = std::system("/home/<user>/helloworld.sh");

/* Example in C/C++ */
#include <stdlib.h>
int ret = system("/home/<user>/helloworld.sh");

The second way is not that easy, but could be non-blocking (script can be run as parallel process):

/* Example in C/C++ */
#include <unistd.h>
pid_t fork(void);
int execv(const char *path, char *const argv[]);

/* You have to fork process first. Search for it, if you don't know how to do it.
 * In child process you have to execute shell (eg. /bin/sh) with one of these
 * exec* functions and you have to pass path-to-your-script as the argument.
 * If you want to get script output (stdout) on-the-fly, you can do that with
 * pipes. Just create the reading pipe in parent process before forking
 * the process and redirect stdout to the writing pipe in the child process.
 * Then you can just use read() function to read the output whenever you want.
 */
Vojtech Vitek - golang.cz
  • 25,275
  • 4
  • 34
  • 40
  • since the OP asked for a C++ way, you should not mention things like fork/execv... and btw, when you use fork already, there is no reason to use execv instead of execv, or is there ? – smerlin Jul 07 '10 at 22:51
0

if you also want to get the output of the script do

char fbuf[256];
char ret[2555]; 
FILE *fh;
if ((fh = popen("./helloworld.sh", "r")) == NULL) {
    return 0;
}else{
    while ( fgets(fbuf, sizeof(fbuf), fh) ) {   
     strcat(ret, fbuf);            
     }          
}
pclose(fh);
valexa
  • 4,462
  • 32
  • 48