Vikas Dubey
Vikas Dubey

Reputation: 37

Bad Substitution Error with System command in C

I have written a C program with some system command in it. I use a software called Gromacs. Here is the snippet of C code :-

       #include<stdio.h>
       #include <stdlib.h>

      /*I have removed unnecessary code, which works fine for me. */   

      int main() {

            float LAMBDA=0.37;

            for(LAMBDA=0.37 ; LAMBDA <0.55; LAMBDA +=0.02 ) {

            system("g_bar -f md*.xvg -o -oi -oh");
            system("mapfile -t a < <(g_bar -f md*.xvg -o -oi -oh | sed '/lambda/s/.*DG *//')");

            printf("Free Energy:\t ");
            system("echo ${a[120]}");

       return 0;
     }

I receive an error

      sh: 1: Bad substitution

I have checked previous answers on Bad substitution. It seems dash doesn't work with arrays then how can I enable Bash for system commands ? If somebody can troubleshoot me I will be grateful.

Upvotes: 0

Views: 758

Answers (2)

cdarke
cdarke

Reputation: 44364

First, mapfile is a bash 4 builtin command. system runs sh, not bash.

Second, and the cause of the error message, you are using process substitution here:

<(g_bar -f md*.xvg -o -oi -oh | sed '/lambda/s/.*DG *//')

sh does not support process substitution. system runs sh, not bash.

You have several calls to system. Your last call (as shown) looks at a variable a that was created in a previous shell process, it won't exist anymore!

I suggest you write a bash script, complete with #!/bin/bash, and call that from C. You could always write out the script from C, using fopen and fprintf.

If that isn't practical, the use bash -c as suggested by @jbm. But you can't expect any persistence across calls to system except via the C program.

Upvotes: 0

jbm
jbm

Reputation: 3163

The sh vs dash vs bash is not the root problem here.

You create a 'a' (whatever that is) in your second call to system().

Then you try to use this 'a' in the forth system() call.

But this is another shell, and 'a' does not exist here.

Each time you call system(), a new shell environment is created, and disappear at return.

What you need to do is somehow save your 'a' to some file that a subsequent call may work on.

In other words, each call to system() act as if you opened a new terminal, do your stuff and then closed it. The variables created in one terminal (shell session) do not exist in the following one.

EDIT:

And to convince you that the sh/dash/bash is not your root problem here, once you've check your commands run OK when typed in the same shell session (terminal), you can always explicitly use bash in your system() calls by;

system("bash -c do_my_stuff from_this and_that etc");

Upvotes: 5

Related Questions