Skip to content

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

I have the following difficult to read script consisting of a single 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?

UPDATE:

If all JAR-files would be located in the same dir, I could have used the new Java 8 wildcard syntax java -classpath "/that/dir/*" de.afarber.MyServlet – but that wasn’t the case here.

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