BashスクリプトとJava間のクラスパスの問題

BashスクリプトとJava間のクラスパスの問題

コンテンツ/opt/scripts/jvm/jvm.script.sh

#!/bin/bash
JAVA_HOME='/java'
PATH="$PATH:/$JAVA_HOME/bin"
java -cp ./classes:./lib com.mystuff.bar.foo.myclass &

コンテンツ/etc/init.d/init.script.sh

home='/opt/scripts/jvm'
program=jvm.script.sh
su scriptuser -c "$home/$program"

/opt/scripts/jvm記号でつながる/data/shellscripts/data/shellscripts実際のディレクトリとして存在することを意味)

initスクリプトの実行に失敗しましたが、cannot find class com.mystuff.bar.foo.myclass 同じユーザーにsuして実行すると機能します。なぜですか?

実行するとをsu scriptuser -c 'declare -p JAVA_HOME'取得しますJAVA_HOME not foundが、まずsu scriptuserユーザーとしてsu(使用)し、実行すると次のようになります。JAVA_HOME="/java"

奇妙に聞こえるかもしれませんが、initスクリプトのhome変数に末尾のスラッシュを追加すると効果があるようです。

だから:

home='/opt/scripts/jvm'

~になる

home='/opt/scripts/jvm/' 

環境要因がシンボリックリンクの処理方法を混乱させるようです。

答え1

これはパスとsu'ingに関する混乱した質問です。このコマンドを実行すると:

$java -cp ./classes:./lib com.mystuff.bar.foo.myclass

Javaが./classesまたは./libでクラスを見つけることができないことを意味する「クラスが見つかりません」を取得します。もし

a) 絶対パスを使用するか b) コマンドを実行する前に正しい場所に cd します (su scriptuser -c "cd $home ; ./$program")。

より安定して動作します。

ホームの後ろに「/」を追加すると、なぜ違いがあるのか​​は奇妙に見えます。 strace/truss を分析し、コマンドが実行するシステムコールを確認できます。この答えはPOSIX仕様を引用しています。

Linuxはマルチパス区切り文字(/home////username///file)をどのように処理しますか?

そして、「ディレクトリエントリで動作するプログラムの場合、fooがディレクトリへのシンボリックリンクである場合、foo /を渡すことは、プログラムがシンボリックリンクではなくディレクトリで動作するようにする方法です」と言います。

関連情報