Content of /opt/scripts/jvm/jvm.script.sh

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

Content of /etc/init.d/init.script.sh

su scriptuser -c "$home/$program"

/opt/scripts/jvm is symlinked to /data/shellscripts (meaning /data/shellscripts exists as a real directory).

Running the init script fails with cannot find class com.mystuff.bar.foo.myclass but if I su to the same user and run it, it works, why?

When I run su scriptuser -c 'declare -p JAVA_HOME' I get JAVA_HOME not found, but if I su to the user first (using su scriptuser) and run it, I get JAVA_HOME="/java"

This may sound crazy, but it seems to fix the issue if I add a trailing slash to the home variable in the init script.





It almost seems like something environmental is messing with the way the symlinks are being handled.

  • What is the output of declare -p JAVA_HOME? Commented Nov 24, 2014 at 21:28
  • @HaukeLaging When I run su scriptuser -c 'declare -p JAVA_HOME' I get JAVA_HOME not found, but if I su to the user first and run it, I get JAVA_HOME="/java". Commented Nov 24, 2014 at 21:49
  • 1
    Please edit your question to add extra information, it is hard to read and easy to miss in the comments.
    – terdon
    Commented Nov 24, 2014 at 23:48
  • "but if I su to the same user and run it, it works" – How do you do that, with su scriptuser or with su - scriptuser? Commented Nov 25, 2014 at 14:26
  • I become scriptuser via su scriptuser. This seems to work fine. Commented Nov 25, 2014 at 14:36

1 Answer 1


It's a confusing question with the paths and su'ing. When you run this command:

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

And get 'class not found', that means java is not able to find that class in ./classes or ./lib. If you either

a) use absolute paths, or b) cd to the right place before running the command (su scriptuser -c "cd $home ; ./$program")

it will work more reliably.

As for why adding a "/" to home makes a difference, that does seem very strange. You could break out strace/truss and see what system calls the command is making. This answer quotes from the posix spec:

How linux handles multiple path separators (/home////username///file)

and says "For programs that act on a directory entry, if foo is a symbolic link to a directory, then passing foo/ is a way to make the program act on the directory instead of the symbolic link."

  • I am not confused about that, I am sure you are right, but I only have control over the init script, not the bash script which calls the JVM. I understand that class not found is because the relative pathing in the class path is not working as expected. What I am confused about is why does it make a difference if I su to the user and run the jvm script versus calling the script with su USER -c script if my working directory is the same in both cases. Commented Nov 25, 2014 at 15:53
  • Not saying you're confused, meant to say the question is confusing with all the paths and su'ing ;-) I've edited my answer to suggest a way to make it the same no matter what, as well as added a link to another question that may explain the difference with the extra slash. Commented Nov 26, 2014 at 6:53
  • Thanks for your input! Because of my inability to edit the called script, I am going to chalk this up to environmental issues and relative pathing. Commented Dec 1, 2014 at 16:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .