You are not logged in.

#1 2009-11-24 18:23:29

DingoMD
Member
Registered: 2008-10-21
Posts: 13

Shell script: function doesn't set global variable when piped

Hey there, just started to play around with some bash scripting and I bumped into this issue today.

My code:

#!/bin/sh

MY_VAR=0
echo "First: $MY_VAR"

my_func() {
    MY_VAR=1
}   

my_func | grep "Fail"
echo "Pipe: $MY_VAR"

my_func
echo "Func: $MY_VAR"

Result:

First: 0
Pipe: 0
Func: 1

I assume that bash is starting a subshell to run my function when piping the result to grep. Is there any way to set the variable and pipe the output at the same time?

Offline

#2 2009-11-24 19:44:08

brisbin33
Member
From: boston, ma
Registered: 2008-07-24
Posts: 1,796
Website

Re: Shell script: function doesn't set global variable when piped

nice catch.

while grepping through man bash i found this sentence in the section about Pipelines:

Each command in a pipeline is executed as a separate process (i.e., in a subshell).

seems to answer your question.  variables set in a subshell do not propagate up.

/edit: what if you export MY_VAR=1 in the function?

/edit2: nope, that doesn't work either...

Last edited by brisbin33 (2009-11-24 19:49:16)

Offline

#3 2009-11-24 20:08:41

DingoMD
Member
Registered: 2008-10-21
Posts: 13

Re: Shell script: function doesn't set global variable when piped

Thanks, that does confirm why it doesn't work as expected. At the moment my only solution is something along the lines of:

#!/bin/sh

MY_VAR=0

my_func() {
    MY_VAR=1
    #echo "Some Text"
    MY_OUTPUT="Text that I was going to echo"
}   

my_func
echo $MY_OUTPUT | grep "Text"

This sets MY_VAR to 1 as expected and I can still pipe the output to some other application but it looks awfully hackish, not to mention that it requires me to change every 'echo' to some var...
If anyone comes up with a better solution I'll be glad to hear it.

Offline

#4 2009-11-25 20:16:33

djszapi
Member
From: Cambridge, United Kingdom
Registered: 2009-06-14
Posts: 1,439
Website

Re: Shell script: function doesn't set global variable when piped

Does this have to be a #!/bin/sh script in fact ? if it does, then your solution is probably the best option
You could also use a FIFO if you run grep in the background, e.g. mkfifo funcout;   grep "Text" funcout & my_func > funcout; wait, then rm funcout when you're done.
(set a trap to rm it on a signal, if you're pedantic, and generate a temporary filename, probably)

Last edited by djszapi (2009-11-25 20:18:36)

Offline

Board footer

Powered by FluxBB