# bash: "undefined variable" and pipe

**URL:** <https://community.unix.com/t/bash-undefined-variable-and-pipe/185925>\
**Category:** Shell Programming and Scripting\
**Created:** [February 18, 2008, 6:20am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925 "2008-02-18T06:20:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![nagaidhlig](https://community.unix.com/letter_avatar/nagaidhlig/32/6_449c533f586939b6e5f246632a46421f.png) [@nagaidhlig](https://community.unix.com/u/nagaidhlig)\
**Post date:** [February 18, 2008, 6:20am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/1 "2008-02-18T06:20:43Z")

</div>

Hi,  
haven't found anything about this through searching, so may be a new topic:  
when doing this:

set -o nounset  
set -o errexit  
find . -name "\*.lib" | while read library; do  
echo ${libary}  
done  
echo "after while"

I expect the script to exit within the while loop (because of nounset and the typo libary!=library). Actually, the script continues, probably because the pipe is executed in a subshell. But shouldn't the undefined variable error propagate up to the calling shell and trigger a non-zero exit?  
Is there an option or way to force this?  
Thanks in advance.

---

<div class="post-metadata">

**Author:** ![radoulov](https://community.unix.com/user_avatar/community.unix.com/radoulov/32/489_2.png) [@radoulov](https://community.unix.com/u/radoulov)\
**Post date:** [February 18, 2008, 7:17am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/2 "2008-02-18T07:17:00Z")

</div>

[bash]

```nohighlight
$ trap "echo I\'m out..." exit
$ set -o nounset -o errexit
$ find ./t -name "*.lib"|while read library; do echo $libary; done
bash: libary: unbound variable
$ while read library; do echo $libary; done< <(find ./t -name "*.lib")
bash: libary: unbound variable
I'm out...

```

---

<div class="post-metadata">

**Author:** ![nagaidhlig](https://community.unix.com/letter_avatar/nagaidhlig/32/6_449c533f586939b6e5f246632a46421f.png) [@nagaidhlig](https://community.unix.com/u/nagaidhlig)\
**Post date:** [February 18, 2008, 8:00am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/3 "2008-02-18T08:00:31Z")

</div>

Thanks for your answer, radoulov, but I'm not sure that's the solution, because the trap doesn't catch within the pipe, only when the script ends:

my script is called "b":  
trap "echo I\'m out..." exit  
set -o nounset -o errexit  
find ./t -name "\*.lib"|while read library; do echo $libary; done  
echo the end

$ sh b  
b: line 3: libary: unbound variable  
the end  
I'm out...

Anyway this would trap \*all\* exits, the good ones as well as the bad ones, which is not what I'm after. I want the script "b" to exit with a non-zero return value as soon as it's encountering the unbound variable, even befor the while loop is completed.

---

<div class="post-metadata">

**Author:** ![radoulov](https://community.unix.com/user_avatar/community.unix.com/radoulov/32/489_2.png) [@radoulov](https://community.unix.com/u/radoulov)\
**Post date:** [February 18, 2008, 8:18am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/4 "2008-02-18T08:18:51Z")

</div>

The trap was only for the visual effect  
the point was the process subsitution,  
consider this:

```nohighlight
% cat s
#!/bin/bash -ue

find ./t -name "*.lib"|while read library;do
  echo $libary
done

echo after the first loop # you'll see it

while read library;do
  echo $libary
done< <(find ./t -name "*.lib")

echo after the second one # you won't see it

ubuntux% ./s
./s: line 4: libary: unbound variable
after the first loop
./s: line 10: libary: unbound variable

```

---

<div class="post-metadata">

**Author:** ![chella](https://community.unix.com/letter_avatar/chella/32/6_449c533f586939b6e5f246632a46421f.png) [@chella](https://community.unix.com/u/chella)\
**Post date:** [February 18, 2008, 8:18am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/5 "2008-02-18T08:18:59Z")

</div>

Hi,

Try this script. This may help you.

```nohighlight
set -o nounset
#set -o errexit
find . -name "*.txt" | while read library; do
echo ${libary}
done
RC=$? #return status of the previous command
if [$RC -ne 0]
then
        exit
fi
echo "after while"

```

Regards,  
Chella

---

<div class="post-metadata">

**Author:** ![nagaidhlig](https://community.unix.com/letter_avatar/nagaidhlig/32/6_449c533f586939b6e5f246632a46421f.png) [@nagaidhlig](https://community.unix.com/u/nagaidhlig)\
**Post date:** [February 18, 2008, 9:08am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/6 "2008-02-18T09:08:30Z")

</div>

Thanks chella, but your example only warns when you expect an error. My point was that an unsuspected "unbound variable" could get unnoticed.

radoulov, that works. I got a bit confused by the different behaviours of "./s" and "sh s" (the latter gives a syntax error).  
Although, as I said, I was looking more for a setting that would raise an error with the existing code, rather than using a different construct, because when I know where to look, I can check unbound variables easily by hand.  
Anyway, it probably is a feature in bash (not a bug) so I just have to be watchful.

Thank you very much again!

---

<div class="post-metadata">

**Author:** ![radoulov](https://community.unix.com/user_avatar/community.unix.com/radoulov/32/489_2.png) [@radoulov](https://community.unix.com/u/radoulov)\
**Post date:** [February 18, 2008, 9:47am UTC](https://community.unix.com/t/bash-undefined-variable-and-pipe/185925/7 "2008-02-18T09:47:21Z")

</div>

> [@nagaidhlig](#):
>
> Thanks chella, but your example only warns when you expect an error. My point was that an unsuspected "unbound variable" could get unnoticed.
> 
> radoulov, that works. I got a bit confused by the different behaviours of "./s" and "sh s" (the latter gives a syntax error).  
> Although, as I said, I was looking more for a setting that would raise an error with the existing code, rather than using a different construct, because when I know where to look, I can check unbound variables easily by hand.  
> Anyway, it probably is a feature in bash (not a bug) so I just have to be watchful.  
> [...]

I think you should understand the difference between sh command and  
./command  
(in the first case the shebang is only a comment):  
Try changing the script like this:

```plaintext
% cat s
#!/bin/bash -ue
find ./t -name "*.lib"|while read correct;do
  echo $wrong
  echo $correct
done||exit

echo after the loop

% ./s
./s: line 3: wrong: unbound variable
% sh s

./t/1.lib
after the loop
% sh -ue s
s: 5: wrong: parameter not set

```

Consider this:

```plaintext
% cat s
#!/bin/bash -ue

find ./t -name "*.lib"|while read correct;do
  echo $wrong
  echo $correct
done

echo after the loop

% sh s

./t/1.lib
after the loop
% sh -uevx s
#!/bin/bash -ue

find ./t -name "*.lib"|while read correct;do
  echo $wrong
  echo $correct
done
+ find ./t -name *.lib
+ read correct
s: 1: wrong: parameter not set

```
