I am calling a shell script from a \'c\' program and have some variables in c which I would like to pass as arguments to the shell script. I tried using the system() to call
You will have to construct a string which contains the full command line for system
to execute. Simplest is probably using sprintf
.
char buf[100];
sprintf(buf, "progname %d %s", intarg, strarg);
system(buf);
That's the quick way for starters.
But there's also the power-duo of fork
and exec
(for unix systems, at least). If your arguments are already separate strings, this can be easier than a really complicated format specification; not to mention calculating the correct buffer size for a complicated format specification!
if (fork() == 0) {
execl(progname, strarg1, strarg2, (char *)NULL);
}
int status;
wait(&status);
if (status != 0) {
printf("error executing program %s. return code: %d\n", progname, status);
}
shell script (a.sh):
# iterates over argument list and prints
for (( i=1;$i<=$#;i=$i+1 ))
do
echo ${!i}
done
C code:
#include <stdio.h>
int main() {
char arr[] = {'a', 'b', 'c', 'd', 'e'};
char cmd[1024] = {0}; // change this for more length
char *base = "bash a.sh "; // note trailine ' ' (space)
sprintf(cmd, "%s", base);
int i;
for (i=0;i<sizeof(arr)/sizeof(arr[0]);i++) {
sprintf(cmd, "%s%c ", cmd, arr[i]);
}
system(cmd);
}
This is not going to print return status of the child process.
The return status is a 16 bit word. For normal termination: byte 0 has a value of zero, and return code is in byte 1 For termination due to an uncaught signal: byte 0 has the signal number and byte 1 is zero.
To print the return status you will need to do something like:
while ((child_pid =wait(&save_status )) != -1 ) {
status = save_status >> 8;
printf("Child pid: %d with status %d\n",child_pid,status);
This below program have worked for me
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char const *argv[])
{
char buf[1000]; //change this length according to your arguments length
int i;
for (i=0;i<argc;i++) {
if(i==0)
{
sprintf(buf, "%s", "sh shell-scriptname.sh");
sprintf(&buf[strlen(buf)]," ");
}
else
{
sprintf(&buf[strlen(buf)],argv[i]);
sprintf(&buf[strlen(buf)]," ");
}
}
//printf("command is %s",buf);
system(buf);
}
My Shell script had arguments like
sh shell-scriptname.sh -a x -b y -c z -d blah/blah/blah
I complied the C program using the following
gcc c-programname.c -o utility-name
To execute
./utility-name -a x -b y -c z -d blah/blah/blah
worked for me