让使用脚本启动的正在运行的进程退出(MineCraft 服务器)

让使用脚本启动的正在运行的进程退出(MineCraft 服务器)

我有一个 MineCraft 服务器,以 中的脚本启动chrontab。当我启动我的 Ubuntu 20.04 LTS 计算机并通过 SSH 连接到服务器时,我想例如将某人添加到白名单中,但我需要让服务器的进程在前台运行,但不知何故,命令jobs -l没有显示该进程,即使htop清楚地显示它正在使用进程 ID 运行。

当我尝试将程序的进程 ID 置于前台时,它只是说-bash: fg: 1328: no such job(本例中 1328 是 java 作业)

我甚至可以将程序置于前台,以便我可以执行诸如/op、和之类的命令/kick,或者whitelist add <name>当我通过中的脚本启动程序时chrontab,或者这是不可能的?

我还想补充一点,用户是同一个,这意味着我想在同一个用户上将该进程置于前台。

答案1

背景:

您只能在最初将进程/程序发送到后台的同一终端中将其带到前台...另一方面,您要问的是从其控制终端分离和转移正在运行的进程/程序并将其附加到新终端...那是完全不同的事情,而且并不容易(对于普通用户)...当该进程有子进程时,情况会变得更加困难(其下的子流程)......孩子越多,事情就越困难、越复杂。

如果你的主进程是用脚本文件启动的,那么你可能希望通过这种方式获取它的 PID:

pgrep -f "ScriptFileName.sh"

更改ScriptFileName.sh为脚本的实际文件名。

要考虑的方法:

第一种方法

目前还没有保证可以轻松实现这一点的方法,但是可以使用以下工具雷普特和别的)尝试使用跟踪...reptyr在 Ubuntu 存储库中可用,因此您可以像这样安装它:

sudo apt install reptyr

并尝试它是否适合您...可以像这样使用:

reptyr PID

或者像这样:

reptyr -T PID

需要然而,要么改变ptrace_scope1默认但会阻止reptyr附加进程) 到0重启后将恢复,或者您可以在完成后将1其设置回最佳安全性1)像reptyr这样工作:

echo "0" | sudo tee /proc/sys/kernel/yama/ptrace_scope

或者sudo像这样使用:

sudo reptyr PID

第二种方法

还有一些方法可以创建命名管道并使用地理数据库将其附加到正在运行的进程的 STDIN 或 STDOUT,以便能够写入(发送参数) 或读到(查看输出)但是,这有点复杂,并且可能不会像第一次预期的那样工作(GDB 是源代码级调试器,而不是常规的用户程序)...但是,执行此操作的过程看起来像这样(只是为了演示...你会遇到问题...自己解决吧):

  • 为进程的 STDIN 创建一个命名管道,如下所示:

    mkfifo /tmp/in_pipe
    
  • 为进程的 STDOUT 创建一个命名管道,如下所示:

    mkfifo /tmp/out_pipe
    
  • 像这样附加流程:

    sudo gdb -p PID
    
  • 像这样关闭当前进程的 STDIN:

     call close(0)
    
  • 重新打开进程的 STDIN 并将其附加到命名管道,如下所示(GDB 可能会挂起,直到管道第一次被使用/写入,但请按照以下两个步骤操作):

    call open("/tmp/in_pipe", 0)
    
  • 从另一个终端,写入您想要传递给正在运行的进程的命名管道参数,如下所示:

    echo "arg1 arg2 ..." > /tmp/in_pipe
    
  • 请注意,如果它看起来像是停止了,您可能需要返回 GDB 终端并继续该过程:

    continue
    
  • 关闭当前进程的 STDOUT,如下所示:

     call close(1)
    
  • 重新打开进程的 STDOUT 并将其附加到命名管道,如下所示(GDB 可能会挂起,直到第一次使用/读取管道,但请按照以下两个步骤操作):

    call open("/tmp/out_pipe", 1)
    
  • 从另一个终端,从命名管道读取正在运行的进程的输出,如下所示:

    cat /tmp/out_pipe
    
  • 注意,你可能需要返回再次进入 GDB 终端,如果出现停止的情况则继续该过程,如下所示:

    continue
    

第三种方法

进程控制终端中的文件描述符在下方可用,您可以通过以下方式/proc/PID/fd/向脚本/进程发送参数:/proc/PID/fd/0

echo "arg1 arg2" > /proc/PID/fd/0

仅有的如果您选择运行脚本/进程来从管道读取(否则,参数只会发送到控制终端的 STDIN,但不会转发到脚本/进程)最初是这样的:

cat | scriptfile

/proc/PID/fd/1您还可以使用以下命令读取进程的 STDOUT :

cat /proc/PID/fd/1

第四种方法(仅追踪

还有斯特拉斯你可以使用它来跟踪这个过程,像这样:

sudo strace -p PID

或者仅仅读取进程的输出,像这样:

sudo strace -p PID -e write

相关内容