vmpstr
vmpstr

Reputation: 5211

bash: executing an output of a script as a script

I'm writing a simple script to generate all combinations of a and b of a given length (say 10). I want to be able to do this on a command line (I know this is fairly easy if I just put everything in a bash script file and execute it). However, I was wondering if it's possible to do without any extra files. Here's what I have so far:

n=10;
for i in `seq 1 1 $n`; do
    echo "for a$i in {a..b}; do ";
done;
echo -n "echo ";
for i in `seq 1 1 $n`; do
    echo -n '$'"a$i"; done;
    echo;
for i in `seq 1 1 $n`; do
    echo "done;";
done

(I formatted the code for readability, but it's actually all on one line run from a prompt)

This gives me the following output:

for a1 in {a..b}; do 
for a2 in {a..b}; do 
for a3 in {a..b}; do 
for a4 in {a..b}; do 
for a5 in {a..b}; do 
for a6 in {a..b}; do 
for a7 in {a..b}; do 
for a8 in {a..b}; do 
for a9 in {a..b}; do 
for a10 in {a..b}; do 
echo $a1$a2$a3$a4$a5$a6$a7$a8$a9$a10
done;
done;
done;
done;
done;
done;
done;
done;
done;
done;

which is just fine. If I copy that and paste it back on the command line, it works like a charm and gives me the result.

The question is how do I do this with just the initial script, without copy-pasting and without redirecting anything to files.

I've tried sticking $( ) around the script, but that gives me "No command 'for' found'", since it's not really a command but a bash builtin. I've tried putting eval somewhere before this, but I just keep getting more errors. I'm a bit stuck, so any help would be greatly appreciated.

(Btw, just to reiterate, I'm doing this more or less to just learn bash more -- that's why I don't want to redirect the output to a file and then execute that file. I know how to do that part, but I don't know how to just do it from command line)

Upvotes: 7

Views: 11737

Answers (2)

Dennis Williamson
Dennis Williamson

Reputation: 359955

You can do for i in $(seq $n) instead of seq 1 1 $n.

You can do for ((i=1; i<=$n; i++)) and avoid calling an external utility.

You can do this (slightly hacky with only one loop):

$ a=A; b=B; n=4; s=''; for ((i=1;i<=n;i++)); do s+="{$a..$b}"; done; eval echo "''" $s"$'\n'"

or this (highly hacky without any loops):

$ a=A; b=B; n=4; eval echo "''" $(printf "{$a..$b}%.0s" $(eval echo "{1..$n}"))"$'\n'"

Either one will get you this:

 AAAA
 AAAB
 AABA
 AABB
 ABAA
 ABAB
 ABBA
 ABBB
 BAAA
 BAAB
 BABA
 BABB
 BBAA
 BBAB
 BBBA
 BBBB

Upvotes: 2

wich
wich

Reputation: 17117

You need to use an eval, $() gives you a string.

eval $( echo echo foo )

Another option is to stick into a subshell and pipe it to a bash:

(echo echo foo) | /bin/bash

Upvotes: 23

Related Questions