
Estou configurando um classpath java em um script bash. Eu pensei que teria que usar aspas para evitar que o shell expandisse *
com base nesta pergunta:https://stackoverflow.com/questions/219585/setting-multiple-jars-in-java-classpath, mas o seguinte funciona bem sem aspas:
classpath=/jars/*:/anotherJarsDir/*
java -classpath=$classpath com.test.MyClass
No entanto, o shell irá expandir isso:
classpath=/jars/*
java -classpath=$classpath com.test.MyClass
Parece que não preciso me preocupar com a expansão do shell atrapalhando meu classpath java se houver vários diretórios na variável classpath.
Responder1
classpath=
é a sintaxe do shell para atribuir uma variável, para que o shell saiba que o que vem depois pode ser um caminho para expandir. isso significa que temos que olhar para /jars/*
e /jars/*:/anotherJarsDir/*
. o primeiro tem um prefixo de diretório e um curinga, o segundo é interpretado como "qualquer arquivo em um diretório chamado anotherJarsDir
, em um diretório que termina em dois pontos (este é o *:
), no /jars
diretório.
Observe que o shell não sabe que os dois pontos são um separador de caminho; ele o interpreta como parte do nome do diretório. Se você tivesse um file /jars/wx:/anotherJarsDir/yz
, então seu caminho corresponderia a isso, mas vários arquivos seriam separados por espaços, não por dois pontos, e java, por sua vez, interpretaria isso como um /jars/wx
arquivo e um /anotherJarsDir/yz
arquivo (assumindo que este é o único arquivo, portanto não resultando em espaços no seu caminho de classe)
Conclusão: se você quiser evitar a expansão, cite suas strings, mesmo que uma string sem aspas funcione em casos extremos!
Responder2
O shell só expandirá os curingas se houver correspondências. Se nenhum arquivo corresponder ao padrão, o curinga será preservado. No entanto, Java e o shell discordam sobre o que o :
caractere realmente significa. Na variável de ambiente classpath, ela é usada como separador entre diferentes itens. O shell, por outro lado, considera-o um caractere de diretório válido como qualquer outro. A única razão pela qual o primeiro exemplo não se expande é porque /jars/*:/anotherJarsDir/*
não corresponde a nenhum diretório. Se, contra todas as probabilidades, você tivesse um diretório chamado algo como /jars/123:/anotherJarsDir/456
, os curingas seriam expandidos para refletir isso. Em outras palavras, sempre cite sua classpath
definição.