“其余行”如何设置 ssh 客户端控制台以显示所有(/px aux)java 进程行以了解 java 文件的名称?

“其余行”如何设置 ssh 客户端控制台以显示所有(/px aux)java 进程行以了解 java 文件的名称?

在此输入图像描述

  • 我的主机上运行着 3 个 java 进程 - 我通过 ssh 客户端访问主机。其中某个进程冻结了,我需要杀死该 pid 进程才能重新启动它
  • 我知道文件名,但不知道文件号。
  • 该进程正在屏幕内运行。如果我在屏幕上加入,则 java 进程已打开并正在运行,并且我无法通过命令停止它或ctrl+c导致其冻结。我看到的独特解决方案就是杀死它。
[root@vmi1478348 ~]# screen -ls
There are screens on:
       18043.lob       (Detached)
       10196.fac       (Detached)
       10100.hu3       (Detached)
       9868.bung       (Detached)
  • 该 pid 号与进程 pid 号不同,可能是屏幕 pid 号。所以如果你杀了它,你就不会杀掉你想杀的java进程,杀掉屏幕。

  • 使用ps aux命令我可以检查pid,但是java文件的名称位于java进程行的末尾,并且它不会像图片一样显示在ssh客户端控制台屏幕上。我已经尝试减小字体大小,但问题仍然存在,它没有显示该行的其余部分,已经尝试用鼠标选择该行以在记事本上复制,但它仍然剪切它。有什么解决办法吗?

答案1

所有你需要的是pgrep

pgrep -fa 'file\.jar'
  • -f:强制pgrep将扩展正则表达式与包含文件名的完整调用命令行 进行匹配。
  • -a:强制pgrep输出完整的调用命令行(其中将包括文件名),自动折叠行超出终端的宽度。

通过这样做,您将获得与表达式匹配的进程 ID 列表,以及它们的完整调用命令行,如果需要,每个条目可以很好地折叠到多行中。

此时,您可以选择kill正确的pid,或者传递相同的正则表达式pkill -f来代替pgrep -fa(如果使用第二种方法,请确保您的目标进程只出现在由 生成的列表中,pgrep -fa 'file\.jar'因为这将向所有与正则表达式匹配的进程发出信号file\.jar)。


另一种方式:如果可用,您可以使用htop箭头键向右滚动。


另一种可能的方式:我非常确定screen正确地向进程发出信号也将强制传播并最终终止子进程。我也许会弄清楚这一点并报告回来,我对这个话题有点生疏。


1 从技术上讲,至少在基于 Linux 的系统上当前版本的 procps 实现中,这是传递给进程(或其任何祖先)进行的pgrep最后一个系统调用的参数空格的串联,其中有一些转义个字符,并截断为 128KiB,与 procps' 报告的 pidexecve()相同。ps -wwo args=

答案2

如果您想了解更多命令行,有许多ps实现,包括来自procps¹ 在 Linux 上,您只需添加该-w选项(或w使用您正在使用的 BSD 风格的 API)两次即可获得完整的命令行²:

ps auxww  # BSD-style
ps -Afww  # standard style

procps'ps还有一个-C选项来报告运行给定命令的进程(使用启发式),因此您可以执行以下操作:

ps -fwwC java

列出java进程的完整命令行。

在 GNU/Linux 上,要可靠地查找将file.jar参数之一传递给它(或其祖先)执行的命令的进程,您可以执行以下操作:

grep -lFzx file.jar /proc/*/cmdline

l列出了至少有一个z以 ero 分隔的记录file.jar作为F固定字符串和 e xactly(不是作为子字符串)进行匹配的文件)。

或者将其限制为正在运行的进程/usr/bin/java

find /proc -maxdepth 2 \
  -name cmdline \
  -execdir test exe -ef /usr/bin/java ';' \
  -exec grep -lFzx file.jar {} +

或者使用 shell 更短、更高效zsh

print -rC1 /proc/<2->(e[$'
  [[ $REPLY/exe -ef /usr/bin/java && \0$(<$REPLY/cmdline) = *\0file.jar\0* ]]
  ']:t)

(替换print -rC1kill以终止这些进程)。

使用这种方法,您可以通过将模式更改为 来仅选择那些file.jar在 1 之后作为下一个参数的进程,从而使选择更加严格。-jar*\0-jar\0file.jar\0*

不过,按照@kos的建议使用pkill可能已经足够好了,并且可以通过以下方式变得更严格:

pkill -f '^java (.* )?-jar file\.jar( |$)'

它不如以下可靠:

  • 它不检查正在运行的可执行文件,只检查传递给它的参数。
  • 它可能会遇到 128KiB 限制(例如,在-jar file.jarringly.unlikely.jar一个非常长的 java 命令行末尾的命令行上进行匹配)
  • 'java and lambada' -f 'jam -jar file.jar'当参数与空格连接时,我们会丢失每个参数开始和结束位置的信息,因此它可以匹配例如启动的进程。
  • 如果命令行中存在无法解码为区域设置编码中的字符的字节序列,它将失败。

所有这些都是极不可能的。


1 在使用 Linux 作为内核的非嵌入式操作系统上最常用的一种。

² from procps 仍然限制为 128KiB ,并且要注意旧版本的 Linux 仅公开了从中获取信息的ps命令行(参数列表)的前 4KiB 。/proc/<pid>/cmdlineps

答案3

虽然不是一个好的解决方案,但解决了部分问题,编辑 ssh 客户端的配置并将字体大小更改为1

疯狂的解决方案 在此输入图像描述

除了选择最长的行并在记事本上复制之外,您无法阅读任何内容,我发现了该行:

root 12868 19.2 8.4 5963840 1381788 pts/1 Sl+ 15:45 3:39 java --illegal-access=permit -Duser.timezone=America/Sao_Paulo -Dlog4j2.formatMsgNoLookups=true -Xms1G -Xmx1G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs/ -Daikars.new.flags=true -jar bung.jar nogui

  • 我想要的进程的名称是bung.jar现在我知道 pid12868

相关内容