- 내 호스트에서 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'에서 보고한 것과 동일한 pid입니다 execve()
.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
프로세스의 전체 명령줄을 나열합니다 .
file.jar
GNU/Linux에서 프로세스(또는 조상)가 실행하는 명령에 인수 중 하나를 전달하는 프로세스를 안정적으로 찾으려면 다음을 수행할 수 있습니다.
grep -lFzx file.jar /proc/*/cmdline
( 고정 문자열 과 실제로 일치하는 ero로 구분된 레코드가 하나 l
이상 있는 파일을 나열합니다 (하위 문자열이 아님).z
file.jar
F
x
또는 실행 중인 프로세스로 제한합니다 /usr/bin/java
.
find /proc -maxdepth 2 \
-name cmdline \
-execdir test exe -ef /usr/bin/java ';' \
-exec grep -lFzx file.jar {} +
또는 더 짧고 효율적인 쉘을 사용하십시오 zsh
.
print -rC1 /proc/<2->(e[$'
[[ $REPLY/exe -ef /usr/bin/java && \0$(<$REPLY/cmdline) = *\0file.jar\0* ]]
']:t)
( 이러한 프로세스를 종료하려면 print -rC1
로 바꾸십시오 kill
).
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를 커널로 사용하는 비임베디드 운영 체제에서 사용되는 가장 일반적인 것입니다.
ps
procps의 ²는 여전히 128KiB로 제한되어 있으며, 이전 버전의 Linux 에서는 정보를 얻은 명령줄(인수 목록)의 첫 번째 4KiB 만 노출되었다는 점에 유의하세요 ./proc/<pid>/cmdline
ps
답변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
이제 pid를 알고 있습니다.12868