1

我在 bash 中有一个脚本来启动一个 java 程序,我想在它执行后获取程序的 pid。pid 将保存在文本文件中。

现在我有这样的事情:

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

我也试过这样,但它也不起作用。

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

当我以 APP_USER 身份运行时,一切正常,当我以 root 身份运行时,我的 java 程序启动,但 pid 文件创建为空。

4

3 回答 3

6

尝试

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

\在传递给 su 命令之前,后面$!会阻止变量的扩展。

于 2013-05-14T11:59:13.240 回答
1

问题是每个su命令都是用户的单独调用,因此$!不会存储您的最后一个 PID,因为没有一个。

您需要做的是将您的 PID 保存在与第一个相同的调用中su。最简单的方法是在两个命令两边加上引号并用分号分隔它们

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

现在su将在同一环境中调用这两个命令。

于 2013-05-14T12:10:59.460 回答
1

如果您的系统提供了start-stop-daemon它可能更容易使用它而不是创建疯狂的包装器。默认情况下,您可以让用户更改 ( --user) 和 nohup 行为 ( --background)。此外,您可以使用--make-pidfile它将做正确的事情 - 无论您是否切换用户。

于 2013-05-14T13:42:57.983 回答