Domanda

I have a script in bash to start a java program and I want to get the pid of the program after it executes. The pid will be saved in a text file.

Right now I have something like this:

if [ "$USER" == "root" ]
then
    su $APP_USER -c "nohup java $JAVA_OPTS  >> $LOG_OUT 2>> $LOG_ERR &"
    su $APP_USER -c "echo $! > $PID_PATH/$CAT.pid"
else
    nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR &
    echo $! > "$PID_PATH/$CAT.pid"
fi

I also tried like this but it doesn't work neither.

if [ "$USER" == "root" ]
then
    su $APP_USER -c "(nohup java $JAVA_OPTS  >> $LOG_OUT 2>> $LOG_ERR &); (echo $! > $PID_PATH/$CAT.pid)"
else
    nohup java $JAVA_OPTS >> $LOG_OUT 2>> $LOG_ERR &
    echo $! > "$PID_PATH/$CAT.pid"
fi

when I run as my APP_USER all works great, when I run as root my java program starts but the pid file is created empty.

È stato utile?

Soluzione

try

su $APP_USER -c "nohup java $JAVA_OPTS  >> $LOG_OUT 2>> $LOG_ERR & echo \$! > $PID_PATH/$CAT.pid"

\ behind $! prevents expansion of the variable, before passing to the su command.

Altri suggerimenti

The problem is that each su command is a separate invocation of the user, so $! won't store your last PID since there isn't one.

What you have to do is save your PID in the same invocation as the first su. The easiest way to do this is to put quotation marks around both commands and separate them by a semicolon

su $APP_USER -c "nohup java $JAVA_OPTS  >> $LOG_OUT 2>> $LOG_ERR &; "echo $! > $PID_PATH/$CAT.pid"

Now su will invoke both commands in the same environment.

If your system provides start-stop-daemon it may be easier to use that instead of creating crazy wrappers. By default you get the user changing (--user) and nohup behaviour (--background). Additionally you can use --make-pidfile that will do the right thing - whether you switch the user or not.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top