Tuesday, October 23, 2012

Bash script Varaible scope not working in pipe


I found this thing when I try to cat a file and making string for grep

Example i have a file
test.txt
--------------
a
b
c
d
a
b
c
a
b
c

cat test.txt|sort|uniq -c|while read line; do echo $line; done

Now problem arise when i try to assign some values to already defined variable inside while loop in attempt of using this command in bash script

#!/bin/bash
founded=""

cat test.txt|sort|uniq -c|while read line
do
        if [ $(echo $founded|wc -m) -gt 1 ]
        then
                founded=$founded"\|"$(echo $line|cut -d" " -f2)
        else
                founded=$(echo $line|cut -d" " -f2)
        fi
done

echo $founded

------
My expected output is:a\|b\|c\|d
I got : (blank)


I tried to found out the answer and find this interesting fact from the article http://www.kilala.nl/Sysadmin/index.php?id=741

"Bash spawns a new sub-shell when piping commands together. Since Bash is picky about scoping variables to sub-shells, my script doesn't work like I expected it to."



-----------


To making my script working i applied this trick

#!/bin/bash
founded=$(cat test.txt|sort|uniq -c|while read line
do
        if [ $(echo $founded|wc -m) -gt 1 ]
        then
                founded=$founded"\|"$(echo $line|cut -d" " -f2)
                echo $founded
        else
                founded=$(echo $line|cut -d" " -f2)
                echo $founded
        fi
done|tail -1)

echo $founded


And i got my expected output

No comments: