سؤال

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.

هل كانت مفيدة؟

المحلول

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.

نصائح أخرى

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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top