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 the shell script but the variable I pass as argument is considered as a string rather than a variable.
-
Have you tried using `getopt` in the shell-script as shown [**here**](http://stackoverflow.com/q/16483119/319204)?... – TheCodeArtist Aug 12 '13 at 04:14
-
I assume you're using Linux? – Matthieu Aug 12 '13 at 04:25
4 Answers
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);
}

- 3,460
- 2
- 22
- 26
-
I would vote this up if it weren't for that weirdness of `sprintf(cmd, "%s...", cmd, ...)`. Is that strictly legal? – luser droog Aug 12 '13 at 05:20
-
That is a lot of unnecessary copying with that sprintf() ... why not us strlcat() (or at least strncat()) instead? Or alternately, use the result from sprintf to offset cmd and print one parameter after the other? – uliwitness Jul 12 '19 at 07:29
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);
}

- 18,988
- 3
- 53
- 105
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

- 1
- 1

- 1,338
- 13
- 15
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);

- 1