9

I have a program that calls a shell script tool that I made that goes through a directory and zips up files and gets the checksum value and calls some other tools to upload the files. The operation takes roughly 3 to 4 minutes.

I call the script like this:

int result = system("/bin/sh /path/to/my/script");

I've also got the same result by using the exec() family of functions:

int child = fork();
if(child == 0) {
    execl( "/bin/sh", "sh", "/path/to/my/script", (char*)0 );
}

I know with exec you can redirect output to the parent program so it can read the output of the command line tools, but other than that when should you use system as opposed to exec?

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
mjl007
  • 735
  • 2
  • 11
  • 27

2 Answers2

8

Ignoring for the time being that use of system is portable while use of exec family of functions is not portable...

When you combine use of exec family of functions with other POSIX functions such as pipe, dup, wait, you get a lot more control over how to pass data between the parent process and the child process.

When you don't need any of those controls, i.e. you just want to execute a command, then using system is preferable, IMO.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    Mostly agree. However, purely anecdotally, I prefer to have a properly flexible `popen` wrapper (e.g. [Boost.Process](http://stackoverflow.com/q/1683665/560648)) to hand and use that for basically everything. My only problem with that is that Boost.Process is, for some reason, a compilation-time killer. Works nicely though. – Lightness Races in Orbit Apr 19 '17 at 17:14
  • @BoundaryImposition, does that wrapper work with MS VC++? If so, I would love to get my hands on it. – R Sahu Apr 19 '17 at 17:22
  • Click on the link and find out! But I have no reason to believe that the answer is no. – Lightness Races in Orbit Apr 19 '17 at 17:24
  • So from your response I guess the general rule of thumb is to keep it as simple as possible for portability and readability. – mjl007 Apr 20 '17 at 06:19
1

The first system call in your question will do the same, what you are doing in the next piece of code (fork and execl)

From documentation:

 The system() library function uses fork(2) to create a child process
 that executes the shell command specified in command using execl(3)

http://man7.org/linux/man-pages/man3/system.3.html

Pavan Chandaka
  • 11,671
  • 5
  • 26
  • 34
  • 3
    This is wrong. There is no reason for system() to use fork(), and system() is available on platforms that don't support it, for example, Windows. –  Apr 19 '17 at 17:13
  • True.. but his question is specific to linux or some unix like systems as he is using "fork" and "execl" – Pavan Chandaka Apr 19 '17 at 17:14
  • Answering with Linux-only facts (and not even disclosing their platform-specific nature) to a question asking for best practice seems kind of dishonest. – Lightness Races in Orbit Apr 19 '17 at 17:30
  • @BoundaryImposition Yes I agree.... but seeing "fork" and "execl", I am inclined to Unix like systems..... And also earlier when I gave some answers for cross platform..... I was beaten to death ....... saying, where did you see windows in question.... :) – Pavan Chandaka Apr 19 '17 at 17:33
  • 1
    Yeah, so, you missed the point. The point is that the best practice is to _not_ use `fork` or `execl`, so that you _can_ share the code on Windows (and other non-Linux platforms). Instead, you assumed that the Linux approach will be used, to the extent that your answer makes Linux-specific assumptions while discussing `system`, ignoring and not mentioning that actually your answer is platform-specific too. – Lightness Races in Orbit Apr 19 '17 at 22:44