首先抱歉,我的英语不好,而且我是 Linux 新手。
当我这样做时,它可以将进程 ID 写入 pid 文件
start () {
echo -n "Starting someserver.jar: "
java -jar /home/someserver/someserver.jar &
echo $! > /home/hcserver/hcserver.pid
}
并且知道我正在使用此命令,但它无法写入 pid 文件
start () {
echo -n "Starting someserver.jar: "
screen -S someserver java -jar /home/someserver/someserver.jar
echo $! > /home/someserver/someserver.pid
}
我怎样才能获取进程 ID 或者修复这个问题?
编辑:
root@server:/home/someserver# ps -ef | grep java
root 4332 1 0 22:03 ? SCREEN -S someserver java -jar /home/someserver/someserver.jar
root 4333 4332 0 22:03 pts/0 java -jar /home/someserver/someserver.jar
root 4363 3222 0 22:04 pts/3 grep java
我想写4333进程 ID 到 pid 文件
答案1
我不能 100%确定我理解了你的问题,但让我们尝试一下:
$! 将从父 shell 运行,而不是从子进程内部运行
$! 表示后台进程,screen 并不完全是后台进程
另外,screen -S 不会分离屏幕,你可能需要更多的屏幕选项,你可能需要类似
screen -dmS
您也可以在屏幕内部尝试 $$ 和 $BASHPID
你可以使用以下方法找到屏幕的 pid
screen -list | grep someserver | cut -f1 -d'.' | sed 's/\W//g'
杀死屏幕的 pid 也会杀死屏幕内正在运行的所有内容
如果你确定分离屏幕的 pid 不够,请尝试使用 pgrep 获取 java 内容的 pid
答案2
那么,您想用在屏幕上运行的脚本替换在后台启动长时间运行的 java 命令的脚本吗?
我认为您的 screen 尝试实际上存在两个问题。首先,该 screen 命令不会退出/后台运行,直到 java 命令完成(或交互式用户输入某些内容)。其次,它$!
实际上不会完全按照您的要求执行。
为了使屏幕正确进入背景,请使用:
screen -d -m -S someserver java -jar /home/someserver/someserver.jar
该-d -m
组合将在分离(后台)状态下启动屏幕,这通常是启动脚本所需要的。如果 java 进程退出,它将自动退出并清理。
因此,现在您已在启动时正确设置了屏幕背景,您仍然需要获取进程的 pid,以便可以控制(或至少停止)它。但捕获该 pid 实际上相当棘手。我认为您可以通过解析输出screen -ls
、解析/proc/
数据和/或解析ps
输出的某种组合来实现,但这会很棘手。到目前为止,最简单的做法是使用screen
它本身来控制该进程。也就是说,在您的stop()
例程中,不要杀死 java 进程的 pid,而是执行以下操作:
stop () {
echo -n "Stopping someserver.jar: "
screen -X -S someserver quit
}
这将告诉屏幕会话(您之前已经通过它识别-S
)终止其控制下的所有进程并退出。
如果你确实需要子进程的进程 ID,那么类似下面的方法就可以了:
cd /var/run/screen/S-$(whoami)
parentpid=$(ls *.someserver | cut -d. -f1)
pid=$(ps --ppid $parentpid -ho pid)