views:

49

answers:

4

This bash script concatenates the names for jar files to a classpath (variable CP), in the while loop the value is correct but is lost in the subshell as descibed in this related question http://stackoverflow.com/questions/124167/bash-variable-scope

#!/bin/bash
CP="AAA"
func() {
        ls -1 | while read JAR
        do
                if [ ! -z "$CP" ]; then
                        CP=${CP}':'
                fi
                CP=${CP}${JAR}
        done
        echo $CP # <-- prints AAA
}

func

My question is, since I can't figure out which element will be the last one, how can the value be saved.

Do I actually have to save the current value (repeatedly in the loop) to a file?

EDIT:

A colleague came up with this command sequence which works well

ls | xargs echo|tr ' ' :
A: 

Use export CP="AAA" which would allows its value to be available in a subshell.

Amardeep
@Amardeep thanks, it's the way back (from the subshell) what I'm interested in.
stacker
@stacker: Sorry! I misunderstood the direction.
Amardeep
+2  A: 

The issue here is that using while in a pipeline creates a subshell, and a subshell cannot affect its parent. You can get around this in a few ways. For what you are doing now, this will suffice:

for JAR in *; do
    # Your stuff
done

Another thing to note is that you shouldn't rely on parsing ls

This also shows you ways to avoid the subshell.

Daenyth
A: 

You might find using find a bit more versatile.

For example:

export CP=$( find /home/depesz/q/ -maxdepth 1 -type f -name '*.jar' -printf ':%p' | cut -b 2- )

Of course set of find options is dependant on what you need/want.

This one is closer to what you had previously:

export CP=$( find . -maxdepth 1 -type f -name '*.jar' -printf ':%f' | cut -b 2- )
depesz
A: 

Implicit subshells are confusing; always make them explicit by using parentheses. To solve your problem, just move the echo inside the subshell.

#!/bin/bash
CP="AAA"
func() {
  ls -1 | (
    while read JAR
    do
      if [ ! -z "$CP" ]; then
        CP=${CP}':'
      fi
      CP=${CP}${JAR}
    done
    echo $CP
  )
}
func
Mark Edgar