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 re
Here is another solution, which avoid the spawning of a subshell altogether. The key is to capture the loop input into a variable (in my example called "JARS") and then redirect this variable into the loop using << EOF:
JARS=$(ls -1)
while read JAR
do
if [ ! -z "$CP" ]; then
CP=${CP}':'
fi
CP=${CP}${JAR}
done <<EOF
$JARS
EOF
echo $CP
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
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- )
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.
None of these answers seem to get into actually returning the value properly, echoing out the answer is fine with a very simple routine, but say you want output of the script in action, this is useless. I don't have the best answer but I don't have much time to figure it out either, so I'm just going to suggest to output exactly what you want to a temp file and read that (surprised it hasn't been mentioned to date) :
#!/bin/bash
CP="AAA"
func() {
ls -1 | (
while read JAR
do
if [ ! -z "$CP" ]; then
CP=${CP}':'
fi
CP=${CP}${JAR}
done
echo "$CP" > /tmp/cp-value-file
)
}
func
CP=$(cat /tmp/cp-value-file)
echo $CP
Downside: will in some cases need to write to the disk every iteration of the loop.