问题描述:

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.

网友答案:

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
网友答案:

I suggest using heredoc for easy maintenance of this long list of class paths:

#!/bin/bash

# populate array cpath with all the the classpaths each one on different lines
read -d '' -ra cpath<<'EOF'
/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
EOF

# merge them with : as separator in classpath    
printf -v classpath "%s:" "${cpath[@]}"

# execute the java command line
/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
-classpath "$classpath" de.afarber.MyServlet
网友答案:

A sed should do the trick:

colonPATHS=$(echo "$PATHS" | sed -r 's/\s+/:/g') 
echo "$colonPATHS"

The sed turns sequences of whitespace into a ":".

网友答案:

Simple sed can do this

pathwithcolons=`echo $PATHS|sed 's/ \+\\ \+/:/g'`
网友答案:

I've ended up using the following script:

#!/bin/sh

REPO=/Users/afarber/.m2/repository
VERSION=9.3.9.v20160517

CPATHS=/Users/afarber/src/jetty-newbie/WebsocketServlet/target/classes 
CPATHS=$CPATHS:$REPO/javax/servlet/javax.servlet-api/3.1.0/javax.servlet-api-3.1.0.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-http/$VERSION/jetty-http-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-io/$VERSION/jetty-io-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-security/$VERSION/jetty-security-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-server/$VERSION/jetty-server-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-servlet/$VERSION/jetty-servlet-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/jetty-util/$VERSION/jetty-util-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-api/$VERSION/websocket-api-$VERSION.jar
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-client/$VERSION/websocket-client-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-common/$VERSION/websocket-common-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-server/$VERSION/websocket-server-$VERSION.jar 
CPATHS=$CPATHS:$REPO/org/eclipse/jetty/websocket/websocket-servlet/$VERSION/websocket-servlet-$VERSION.jar 

/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home/bin/java \
        -classpath $CPATHS de.afarber.MyServlet

I like it better than other solutions, because it does not spawn additional processes (like sed), is easier to read and can be translated to Windows CMD batch file:

@echo off

set REPO="C:\Users\user1\.m2\repository"
set VERSION=9.3.9.v20160517

set CPATHS=C:\Users\user1\jetty-newbie\WebsocketServlet\target\classes
set CPATHS=%CPATHS%;%REPO%\javax\servlet\javax.servlet-api\3.1.0\javax.servlet-api-3.1.0.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-http\%VERSION%\jetty-http-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-io\%VERSION%\jetty-io-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-security\%VERSION%\jetty-security-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-server\%VERSION%\jetty-server-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-servlet\%VERSION%\jetty-servlet-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-util-ajax\%VERSION%\jetty-util-ajax-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\jetty-util\%VERSION%\jetty-util-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-api\%VERSION%\websocket-api-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-client\%VERSION%\websocket-client-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-common\%VERSION%\websocket-common-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-server\%VERSION%\websocket-server-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\eclipse\jetty\websocket\websocket-servlet\%VERSION%\websocket-servlet-%VERSION%.jar
set CPATHS=%CPATHS%;%REPO%\org\postgresql\postgresql\9.4.1208.jre7\postgresql-9.4.1208.jre7.jar

"C:\Program Files\Java\jdk1.8.0_66\bin\java.exe" -cp %CPATHS% de.afarber.MyServlet
相关阅读:
Top