2013-06-30 146 views
2

我注意到一個反覆出現的問題:在shell腳本內的java命令行上使用env var作爲類路徑不起作用。在shell腳本中使用java classpath的環境變量

首先,讓我們來看看有什麼工作:在腳本中都使用硬編碼的類路徑如下:(注:「類路徑是」語句是Java程序本身內打印)

[email protected]:/shared$  java -classpath .:/shared/mysql-connector-java-5.1.25-bin.jar DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 
classpath is .:/shared/mysql-connector-java-5.1.25-bin.jar 
Attempting connection to com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql password 
Connecting to user using URL=jdbc:mysql://localhost:3306/mysql 
Successfully connected. 

而且使用的環境變量直接在外殼內:

[email protected]:/shared$ export CP=.:/shared/mysql-connector-java-5.1.25-bin.jar 
[email protected]:/shared$ java -classpath $CP DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 
classpath is .:/shared/mysql-connector-java-5.1.25-bin.jar 
Attempting connection to com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql password 
Connecting to user using URL=jdbc:mysql://localhost:3306/mysql 
Successfully connected. 

什麼*不*工作:在運行相同的命令shell腳本中如上圖所示:

[email protected]:/shared$ cat dbping.mysql 
CP=.:/shared/mysql-connector-java-5.1.25-bin.jar 
echo $CP 
java -classpath $CP DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 
#java -classpath .:/shared/mysql-connector-java-5.1.25-bin.jar DbPing com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql user password 

[email protected]:/shared$ ./dbping.mysql 
.:/shared/mysql-connector-java-5.1.25-bin.jar 
classpath is .:/shared/mysql-connector-java-5.1.25-bin.jar 
Attempting connection to com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/mysql password 
Could not load db driver com.mysql.jdbc.Driver 
java.lang.ClassNotFoundException: com.mysql.jdbc.Driver 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
    at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:190) 
    at DbPing.getConnection(DbPing.java:34) 
    at DbPing.main(DbPing.java:22) 
Exception in thread "main" java.sql.SQLException: com.mysql.jdbc.Driver 
    at DbPing.getConnection(DbPing.java:41) 
    at DbPing.main(DbPing.java:22) 

後續:腳本有windows風格的換行符它。很明顯,\ r破壞了內部環境變量。發現這使用

od -cx 

。無論如何,我會給斯蒂芬c,因爲他的刺激讓我走上正確的軌道找到解決方案

+0

我檢查了一些我已經坐的腳本,並且引用了我的類路徑參數,儘管我的一個glob有。出於好奇,你是否得到與java -classpath「$ CP」相同的結果DbPing ...? –

+0

是什麼打印'classpath是...'消息?標準的'java'應用程序啓動器不會那樣做。 – Joni

回答

1

你描述的症狀是相當令人費解的。我看不到問題(腳本看起來正確),但我已經瞭解如何開始追蹤它。

  1. 擺脫註釋掉的腳本。

  2. 將一條#!/bin/sh行添加到腳本的開頭,以確保您實際使用的是正確的shell來執行它。 (這樣做總是一個好主意......即使您認爲默認情況下您將獲得正確的shell,這可能會改變,具體取決於平臺)。

  3. 要弄清楚shell在做什麼,加set -vx後跟#!/bin/sh一致。

「-v」表示echo每個腳本行讀取,而「-x」表示echo回執行的實際命令行。這會告訴你究竟是什麼命令正在運行......這樣你就可以找出命令參數真的是

+0

「classpath is」語句是在java dbPing程序本身內生成的。我使用的是Ubuntu,因此/ bin/sh與/ bin/bash相同,但無論我將添加-vx – javadba

+0

@javadba - 您應該總是放一個#!在任何腳本上行。 1)文件。 2)您的腳本可能需要在將來在另一個平臺上運行,並且您使用不同的shell可能很重要。 3)AFAIK在「/ bin/sh」和「/ bin/bash」之間存在行爲差異,即使它們是相同的可執行文件... –

+0

我發現問題是Windows樣式換行符。但是,我給了你答案,因爲它幫助我用精細的齒梳仔細觀察劇本。 – javadba

相關問題