Skip to main content
added 87 characters in body
Source Link
ilkkachu
  • 147.9k
  • 16
  • 268
  • 441
unset myVariable i;  
while [ -z "$i" ]; do
    read myVariable;
    echo "myVariable : '$myVariable'"; 
 i=foo; done;  i=foo;
done;
echo "myVariable : '$myVariable'"

(the unset is there to allow replaying the command)

press any key + ENTER, you'll get :

myVariable : '[what you typed]'
myVariable : '[what you typed]'

The value of myVariable exists outside of the while loop. Now try :

tmpFile=$(mktemp);  
echo -e 'foo\nbar\nbaz' >> "$tmpFile"; "$tmpFile"
while read myVariable; do
    otherVariable=whatever; 
    echo "myVariable : '$myVariable', otherVariable : '$otherVariable'";  
done < "$tmpFile";  
echo "myVariable : '$myVariable', otherVariable : '$otherVariable'";  
rm "$tmpFile"

you'll get :

myVariable : 'foo', otherVariable : 'whatever'
myVariable : 'bar', otherVariable : 'whatever'
myVariable : 'baz', otherVariable : 'whatever'
myVariable : '', otherVariable : 'whatever'

The value of myVariable is lost when leaving the loop.

Why is there a different behaviour ? Is there a scope trick I'm not aware of ?

NB : running GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

unset myVariable i; while [ -z "$i" ]; do read myVariable; echo "myVariable : '$myVariable'"; i=foo; done; echo "myVariable : '$myVariable'"

(the unset is there to allow replaying the command)

press any key + ENTER, you'll get :

myVariable : '[what you typed]'
myVariable : '[what you typed]'

The value of myVariable exists outside of the while loop. Now try :

tmpFile=$(mktemp); echo -e 'foo\nbar\nbaz' >> "$tmpFile"; while read myVariable; do otherVariable=whatever; echo "myVariable : '$myVariable', otherVariable : '$otherVariable'"; done < "$tmpFile"; echo "myVariable : '$myVariable', otherVariable : '$otherVariable'"; rm "$tmpFile"

you'll get :

myVariable : 'foo', otherVariable : 'whatever'
myVariable : 'bar', otherVariable : 'whatever'
myVariable : 'baz', otherVariable : 'whatever'
myVariable : '', otherVariable : 'whatever'

The value of myVariable is lost when leaving the loop.

Why is there a different behaviour ? Is there a scope trick I'm not aware of ?

NB : running GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

unset myVariable i; 
while [ -z "$i" ]; do
    read myVariable;
    echo "myVariable : '$myVariable'"; 
    i=foo;
done;
echo "myVariable : '$myVariable'"

(the unset is there to allow replaying the command)

press any key + ENTER, you'll get :

myVariable : '[what you typed]'
myVariable : '[what you typed]'

The value of myVariable exists outside of the while loop. Now try :

tmpFile=$(mktemp); 
echo -e 'foo\nbar\nbaz' >> "$tmpFile"
while read myVariable; do
    otherVariable=whatever; 
    echo "myVariable : '$myVariable', otherVariable : '$otherVariable'"; 
done < "$tmpFile"; 
echo "myVariable : '$myVariable', otherVariable : '$otherVariable'"; 
rm "$tmpFile"

you'll get :

myVariable : 'foo', otherVariable : 'whatever'
myVariable : 'bar', otherVariable : 'whatever'
myVariable : 'baz', otherVariable : 'whatever'
myVariable : '', otherVariable : 'whatever'

The value of myVariable is lost when leaving the loop.

Why is there a different behaviour ? Is there a scope trick I'm not aware of ?

NB : running GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)

Source Link
Httqm
  • 1.2k
  • 8
  • 17

Why is a variable global when set with `read variable` inside a `while` loop, but local when set with `while read variable`?

unset myVariable i; while [ -z "$i" ]; do read myVariable; echo "myVariable : '$myVariable'"; i=foo; done; echo "myVariable : '$myVariable'"

(the unset is there to allow replaying the command)

press any key + ENTER, you'll get :

myVariable : '[what you typed]'
myVariable : '[what you typed]'

The value of myVariable exists outside of the while loop. Now try :

tmpFile=$(mktemp); echo -e 'foo\nbar\nbaz' >> "$tmpFile"; while read myVariable; do otherVariable=whatever; echo "myVariable : '$myVariable', otherVariable : '$otherVariable'"; done < "$tmpFile"; echo "myVariable : '$myVariable', otherVariable : '$otherVariable'"; rm "$tmpFile"

you'll get :

myVariable : 'foo', otherVariable : 'whatever'
myVariable : 'bar', otherVariable : 'whatever'
myVariable : 'baz', otherVariable : 'whatever'
myVariable : '', otherVariable : 'whatever'

The value of myVariable is lost when leaving the loop.

Why is there a different behaviour ? Is there a scope trick I'm not aware of ?

NB : running GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)