1

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.

user2430996
  • 341
  • 1
  • 4
  • 12

4 Answers4

1

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);
}
Manoj Awasthi
  • 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
0

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);
}
luser droog
  • 18,988
  • 3
  • 53
  • 105
0

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

Community
  • 1
  • 1
Anandkumar
  • 1,338
  • 13
  • 15
-1

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);
daniel
  • 1