コンテンツ/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 /を渡すことは、プログラムがシンボリックリンクではなくディレクトリで動作するようにする方法です」と言います。