Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am having some problem with bash. I want to export an environment variable whose value contains a variable but I don't want that variable (which is within the value) to be evaluated during the export process. i.e.

export STY=for i in {0..3}; do echo $i; done

so my requirement is that when I echo STY, the output that I need should be

echo $STY
for i in {0..3}; do echo $i; done 

But $i is evaluated during export. I need to preserve it as it is.

Thanks alot for your help.

share|improve this question

migrated from stackoverflow.com Feb 26 '12 at 5:41

This question came from our site for professional and enthusiast programmers.

    
Are you saying that echo $STY should print out the actual text for i in {0..3}; do echo $i; done? Or are you saying that echo $STY should execute that for-loop? (I ask because, although it sounds to me like the former, Borealid below seems to think you really want the latter.) –  ruakh Feb 25 '12 at 1:45
    
Actually I want to setup the environment variable that will contain some code but will be executed in some other bash script. –  Shahzad Feb 25 '12 at 2:01
    
How are you executing the command in the variable? Command substitution? –  Daniel Feb 25 '12 at 2:57
    
I am simply specifying the name of the variable like $hello –  Shahzad Feb 25 '12 at 2:58
1  
Change double quote to single quote, then try: eval $hello –  kev Feb 25 '12 at 3:10

4 Answers 4

If you want what you said you wanted:

export STY="for i in {0..3}; do echo \$i; done"

If you want what you probably actually meant:

function STY() {
    for i in {0..3}; do echo $i; done
}
export -f STY
share|improve this answer
1  
He could just use single quotes, i.e. export STY='for i in {0..3}; do echo $i; done' –  Perry Feb 25 '12 at 1:44
    
@Perry Six one way, half-dozen the other. –  Borealid Feb 25 '12 at 1:45
    
is it possible that we can execute the code contained in environment variable on command line? –  Shahzad Feb 25 '12 at 1:57
    
By the way, if I do export such as export pqr="time ls" and if I specify this variable in some script then the code executes but if I place a for loop within this environment variable then shell yells at me and say for command not found. –  Shahzad Feb 25 '12 at 2:31
    
@Shazard, this answer implies you use SST as function. DATA=`STY()` (note left quotes - they get standard output of expression). To execute non-function variable (closer to your example) use eval $STY –  Basilevs Feb 25 '12 at 2:58

Short: use eval "$hello".

(This answer originally said: use eval $hello but another poster pointed out that eval "$hello" is safer.)

As shown below:

bash-2.05a$ export hello='for i in 0 1 2 3; do echo $i; done'

Simply saying $hello at the beginning of a line does not work - because for loops are processed before $variable expansion (phase oriented languages, I hate 'em):

bash-2.05a$ $hello
bash: for: command not found

But eval'ing works:

bash-2.05a$ eval $hello
0
1
2
3
bash-2.05a$ 

What you were (or might have been) doing wrong:

bash-2.05a$ export hello='for i in {0..4}; do echo $i; done'
bash-2.05a$ $hello
bash: for: command not found
bash-2.05a$ eval $hello
{0..4}
bash-2.05a$ for i in {0..4}; do echo $i; done
{0..4}
bash-2.05a$ 

I.e. at least in the version of bash I am using, {0..4} doesn't do what you thought it should.

http://www.cyberciti.biz/faq/bash-for-loop/ says that the {0..4} feature came in bash 3.0+.

Perhaps you, like me (at woprk, not home), are using an obsolete version of bash?

share|improve this answer
    
Don't use eval $hello, use eval "$hello". Without the double-quotes, some unwanted parsing is done, which can cause very weird bugs. See this answer for an example (in a rather different situation, but the same principles apply). –  Gordon Davisson Feb 25 '12 at 9:20

The reason why $hello doesn't run as you expected:

  • Expansion is performed on the command line after it has been split into tokens.
  • for...do...done is a Compound Command which is determined in tokenlize stage.
  • for is not a command.

So, you cannot do this:

$ "for" i in {0..4}; do echo $i; done
sh.exe": syntax error near unexpected token `do'

When bash split the command-line into tokens, It see "for" not for, so token do is unexpected.


In your case:

$ hello='for i in {0..4}; do echo $i; done'
$ $hello
sh.exe": for: command not found

Bash finds one token $hello, then variable-expansion&&word-spliting take place in order.
Actually, bash parses the result as a Simple Command:

  • command(for) takes rest as args(i,in,{0..4}, ;, do, ...)
  • for, do, ;, done, etc lost their special meanings.

read more for detail

share|improve this answer

The problem has two sides:

  • storing complex expressions in variable
  • executing stored expression

To store expression, escape sequences and special quoting might be needed (that seems to be right in your example). Execution can be performed in two ways:

  • function call as in Borealid's answer: data=`STY()` - standard output of function is stored into variable
  • expression evaluation: data=eval $STY for variable definition given in your example
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.