I'm programming in C to create some API for an embedded device. This embedded device runs a variant of Linux. I'm not very familiar with C - I'm more familiar with shell scripting/bash.
With that in mind, when it comes to things like checking whether a directory exists, or getting disk usage, I find it easier to just make a call to system
or popen
and execute my command, then parse the output. It's faster for me as a developer.
Are there downsides to making these system
and popen
calls instead of finding out how to do each of these things in C and then making use of C's functions?
Cons:
Pros:
system("ls -1");
Summarize -
It depends what you need to do, but in general case there more negatives than positives.
Even if it is going to work on Linux, you can't rely on the availability of all the commands you intend to use, so the downside is straight forward: you can't rely on a given tool being available.
One more thing to consider is that parsing the output of shell commands from c is terribly difficult.
And finally, you can't make your program randomly call a system utility or shell script simply because it's unsafe.
At the end of the day, on a Linux system, pretty much everything is calling C functions at some point.
To touch on some of the arguments in comments as well as my own thoughts:
EDIT to address Pimgd's comment: Note that race conditions are a pain in the neck and a lot of them aren't necessarily an issue for your particular use case, but are at least worth considering when weighing pro's/con's. Anyways, the specific race-condition instances I was thinking about include (and there are likely other classes):
Multi-process race conditions. The simplest example I can think of is what happens if two instances of your program want to set a configuration file and are running at the same time. There are certain OS calls which have certain levels of guarantee on atomicity, but you lose a lot of that if you call a series of shell commands to write to the file. (note that even if you do it from a monolithic C application versus a series of shell commands, you still would need to do something extra to prevent instance 1 from overwriting instance 2's change, but you're at least not likely to run into the case that you end up having changes intermixed. As an example consider:
FILE *fp = fopen("config.txt","wt");
fprintf(fp,"Config value 1: %s",config[0]);
fprintf(fp,"Config value 2: %s",config[1]);
fflush(fp);
fclose(fp);
vs.
system("echo Config value 1: `df | awk '{print $1}'` > config.txt");
system("echo Config value 2: `ps | grep foo | awk '{print $2}'` >> config.txt");
Where, if two instances of the program run at close to the exact time, you can end up with e.g. 2 instances of Config value 2 in the config file in the latter case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With