6

I have a string variable which contains a loop.

loopVariable="for i in 1 2 3 4 5 do echo $i done"

I want to pass this variable to a bash command inside the shell script. But i am always getting an error

bash $loopVariable

i've tried also

bin/bash $loopVariable

But it also doesn't work. Bash treats the string giving me an error. But theoretically it execute it. I am not sure what am i doing wrong

bash: for i in 1 2 3 4 5 do echo $i done: No such file or directory

I have also tried to use this approach using while loop. But getting the same error

i=0 
loopValue="while [ $i -lt 5 ]; do make -j15 clean && make -j15 done"
bash -c @loopValue

when I use bash -c "@loopValue" i get following error

bash: -c: line 0: syntax error near unexpected token `done'

and when i use just use bash -c @loopValue

[: -c: line 1: syntax error: unexpected end of file
4
  • Your while loop should be while [ $i -lt 5 ]; do make -j15 clean && make -j15; done, (missing ; before done), and your bash command: bash -c $loopValue, not bash - c @loopValue. Commented Nov 8, 2016 at 13:04
  • now its giving ` -c: line 1: syntax error: unexpected end of file` Commented Nov 8, 2016 at 13:09
  • My bad... double quote the variable: bash -c "$loopValue" Commented Nov 8, 2016 at 13:11
  • it now complains about unexpected done token Commented Nov 8, 2016 at 13:16

3 Answers 3

11

You can add the -c option to read the command from an argument. The following should work:

$ loopVariable='for i in 1 2 3 4 5; do echo $i; done'
$ bash -c "$loopVariable"
1
2
3
4
5

from man bash:

  -c         If the -c option is present, then commands are read from  the
             first non-option argument command_string.  If there are argu‐
             ments after the command_string,  they  are  assigned  to  the
             positional parameters, starting with $0.

Another way is to use the standard input:

bash <<< "$loopVariable"

Regarding the updated command in the question, even if we correct the quoting issues, and the fact that the variable is not exported, you are still left with an infinite loop since $i never changes:

loopValue='while [ "$i" -lt 5 ]; do make -j15 clean && make -j15; done'
i=0 bash -c "$loopValue"

But it would almost always be better to use a function as in @Kenavoz' answer.

Sign up to request clarification or add additional context in comments.

13 Comments

and what does -c do?
It allows bash to read the command to be executed from the argument list, instead of the standard input.
can i use the same approach with while loop?
@KvyatkovskySergey: Sure, why not? Any valid bash command (or list of commands) is accepted
i am assigning the loopVariable value to while [ 0 -lt 3 ] do make -j15 clean && make -j15 done but getting the same error
|
4

You don't need to open a new process with bash -c. You can use a Bash function instead:

function loopVariable {
  for i in 1 2 3 4 5; do echo $i; done
}

loopVariable

Please note that since no suprocess is created, you don't need to export your variables to use them in a child process as with a bash -c. All of them are available in the script scope.

output:

1
2
3
4
5

Comments

2
loopvariable='for i in 1 2 3 4 5; do echo $i; done'
bash -c "$loopvariable"

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.