问题
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.
回答1:
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.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/16542417/bash-get-pid-of-a-process-using-a-different-user