1

I use Java5 and I don't want to point each .jar file in Classpath so I've tried to write small shell script:

find $LIB_DIR -name '*.jar' -print > /tmp/classpath
CP= 
cat /tmp/classpath | while read line
do 
CP=$CP:$line
done 
rm -f /tmp/classpath

But this is not work - $CP variable is empty.

As a result $CP should be single string with pathes delimited by ':'

Is anyone knows what is wrong here and how to correctly concatenate all file's lines to one string?

nahab
  • 1,308
  • 17
  • 38

3 Answers3

5

Your while loop is in a sub-shell, so no variables will be passed back to the main shell. You want to do something like this anyway:

CP=$(find $LIB_DIR -name '*.jar' -print | tr '\n' ':')

That'll do what you want all on one line.

Steve Baker
  • 4,323
  • 1
  • 20
  • 15
1

The problem is that the while loop runs in a separate shell instance and the local variable in it ($CP) isn't available in the outer shell.

Something like

while read line; do
    CP="$CP:$line"
done < /tmp/classpath

should work. But note that $CP ends up with a colon as first character then so it needs some post-processing.

Moreover you should make use of mktemp otherwise you could be tricked into overwriting files if someone puts a symlink at /tmp/classpath.

Uwe Kleine-König
  • 3,426
  • 1
  • 24
  • 20
0

To make it clear that said Uwe Kleine-König and Steve Baker while-do-done block is not subshell by its nature but because of pipe use in this code block

cat /tmp/classpath | while read line
do 
CP=$CP:$line
done 

From Bash man page: "Each command in a pipeline is executed as a separate process (i.e., in a subshell)."

More about subshells.

See also another SO answer about pipe and subshells.

enter link description here

Community
  • 1
  • 1
nahab
  • 1,308
  • 17
  • 38