두 개의 PID 목록을 ssh를 사용하여 xargs에 전달하여 첫 번째 PID만 종료합니다.

두 개의 PID 목록을 ssh를 사용하여 xargs에 전달하여 첫 번째 PID만 종료합니다.

나는 죽이고 싶은 두 개의 PID 목록을 검색하고 있습니다. 내 파이프라인은 다음과 같습니다.

ps -ef | grep foo | grep -v grep | awk {'print $2'} | xargs kill -9

로컬에서 이 작업을 수행하면 두 프로세스가 모두 종료됩니다. 하지만 SSH와 함께 사용하면

ssh foo@<IP Address> "ps -ef | grep foo | grep -v grep | awk {'print $2'} | xargs kill -9"

두 PID 중 하나만 삭제됩니다. kill: <PID>: No such process두 번째 프로세스를 로컬에서 종료하려고 하는 것이 가능합니까 ?

답변1

로컬 셸 명령줄에서는 $2큰따옴표로 묶이므로 로컬 셸에 의해 확장됩니다(빈 문자열일 수 있음).

따라서 원격 호스트에서 실행되는 명령은 다음과 같습니다.

 ps -ef | grep foo | grep -v grep | awk {'print '} | xargs kill -9

awk명령은 작동하지 않으며(모든 행을 인쇄함) xargs결국 실행됩니다.

 kill -9 <all-the-words-present-in-the-output-of-ps|grep...>

여기에는 pid 및 ppid, 사용자 이름이 포함됩니다.

또한, kill 명령의 pid가 목록에 있으면 스스로 종료되므로 목록에 있는 나머지 프로세스를 종료할 수 없습니다.

원하는 곳은 다음과 같습니다.

ssh foo@<IP Address> 'pkill -KILL -f foo'

(명령줄에 포함된 모든 프로세스를 종료합니다(적어도 처음 몇 킬로바이트) foo.)

또는 원격 시스템에 명령이 없는 경우 pkill:

ssh foo@<IP Address> '
  ps -Ao pid= -o args= |
    awk "/[f]oo/ {print \$1}" |
    xargs kill -s KILL'

awk 코드에 대해 로컬 측에서는 작은따옴표(변수 확장이 없음)를 사용하고 원격 쉘 명령줄에서는 큰따옴표를 사용하므로 원격 쉘에 의해 확장되지 않도록 $in 을 이스케이프해야 합니다 .$1

awk예, superset grep, 일반적으로 함께 파이프할 필요가 없습니다. 사용법에서 알 수 있듯이 ps에 의해 표시되는 매개변수 목록에서 검색한다고 가정하고 일치시키고 싶은 것만 출력하도록 지시하는 것이 좋습니다 ps.foo-f

원격 사용자(여기서는 foo 사용자 및 foo로 sshing)의 모든 프로세스를 종료하려면 다음을 수행할 수 있습니다.

 ssh foo@<IP Address> 'kill -s KILL -- -1'

이렇게 하면 사용자가 종료할 권한이 있는 모든 프로세스가 종료됩니다. 일반 사용자의 경우 실제 또는 저장된 사용자 ID가 종료 프로세스의 실제 또는 유효 사용자 ID와 동일한 모든 프로세스를 의미합니다.

또는:

 ssh foo@<IP Address> 'pkill -KILL -U "$(id -u)"'

(또는 pkill -U foo). 실제 사용자 ID가 원격 사용자의 유효 사용자 ID와 동일한 모든 프로세스를 종료합니다.

아니면 이렇게 할 수도 있습니다:

 ssh foo@<IP Address> '
   trap "" HUP
   ps -Ao sid= -o pid= -U "$(id -u)" |
     awk "\$1 != $(ps -eo sid= -p "\$\$") {print \$2}" |
     xargs kill -s KILL'

( 자신, 쉘 또는 SIGHUP 을 죽이지 sid않도록 선택하고 사용자 프로세스를 죽이면 이 신호가 전송되는 경우 SIGHUP을 무시합니다 )killawkxargssshd

우리는 원격 사용자의 로그인 쉘이 Bourne의 로그인 쉘과 유사하다고 가정합니다. 예를 들어, 원격 사용자의 로그인 쉘이 다른 구문을 가진 csh 또는 rc 제품군에 속하는 경우 이러한 명령을 조정해야 합니다.

번호보다는 이름으로 신호를 참조하는 것이 더 좋습니다. 더 명확하고 신호 번호가 시스템마다 다를 수 있기 때문입니다(SIGKILL의 경우 9는 상당히 보편적입니다).

답변2

요컨대 이것을 시도해보십시오

 ssh user_name@ip_address "pkill -9 foo"

아니면 더 길게 원하시면

 ssh user_name@ip_address "ps aux | grep '[f]oo' | awk '{print \"kill -9 \"\$2}' | bash -v"

관련 정보