Alexander Farber Alexander Farber - 6 months ago 25
Bash Question

Concatenate list of paths in bash-script, with colon as separator

I have the following difficult to read script consisting of just 1 command:

#!/bin/sh

/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar:/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar \
de.afarber.MyServlet


As slight readability improvement I would like to list all the paths after the
-classpath
in a separate variable, each aligned after the other:

PATHS= /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar \
/Users/afarber/.m2/repository/org/eclipse/jetty/websocket/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar


This way I can easier add and remove the paths, and sort them in Vim.

My question is: how to join them back for my command?

Answer

Since you are using bash, you can store the directory names in an array (with some refactoring just to make this example more readable):

repo=/Users/afarber/.m2/repository
jetty="$repo/org/eclipse/jetty"
websocket="$jetty/websocket"
paths=(
    /Users/afarber/src/jetty-newbie/EmbeddedWebsocket/target/classes
    "$jetty"/jetty-server/9.3.9.v20160517/jetty-server-9.3.9.v20160517.jar
    $repo/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar
    "$jetty"/jetty-http/9.3.9.v20160517/jetty-http-9.3.9.v20160517.jar
    "$jetty"/jetty-util/9.3.9.v20160517/jetty-util-9.3.9.v20160517.jar
    "$jetty"/jetty-io/9.3.9.v20160517/jetty-io-9.3.9.v20160517.jar
    "$jetty"/jetty-servlet/9.3.9.v20160517/jetty-servlet-9.3.9.v20160517.jar
    "$jetty"/jetty-security/9.3.9.v20160517/jetty-security-9.3.9.v20160517.jar
    "$websocket"/websocket-api/9.3.9.v20160517/websocket-api-9.3.9.v20160517.jar
    "$websocket"/websocket-server/9.3.9.v20160517/websocket-server-9.3.9.v20160517.jar
    "$websocket"/websocket-common/9.3.9.v20160517/websocket-common-9.3.9.v20160517.jar
    "$websocket"/websocket-client/9.3.9.v20160517/websocket-client-9.3.9.v20160517.jar
    "$websocket"/websocket-servlet/9.3.9.v20160517/websocket-servlet-9.3.9.v20160517.jar 
)

Note you don't need to end each line with a backslash; whitespace (including newlines) separate elements of the array. Once you have the array, you can join the elements with a colon using parameter expansion with a modified value of the IFS parameter.

/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
  -classpath "$(IFS=:; echo "${paths[*]}")" de.afarber.MyServlet