0바이트와 절대 일치하지 않는 pgrep 패턴을 작성하는 방법은 무엇입니까?

0바이트와 절대 일치하지 않는 pgrep 패턴을 작성하는 방법은 무엇입니까?

foo현재 내 계획은 pkill테스트 목적으로 프로세스 친화적으로 스키마를 확인하는 것 입니다 pgrep. 나는 보았다이 문제이는 긴 프로세스 이름의 경우 -f. 이는 긴 프로세스 이름의 나머지 부분을 얻는 데 유용합니다. 문제는 패턴이 프로세스 이름뿐만 아니라 전체 명령줄과 일치한다는 것입니다 foo. 논쟁.

그래서 저는 다음과 같은 패턴을 작성하고 싶습니다.

pgrep -f '^[^\0]*foo'

이것이 의미하는 바는 \00바이트입니다. 즉, -f프로세스의 각 인수 앞에 구분 기호가 배치됩니다. 물론 \0그렇지 않습니다. 패턴은 실제로 \또는 (ASCII) 가 아닌 모든 문자 시퀀스 와 일치합니다 0. 나는 또한 이것을 시도했습니다 :

pgrep -f '^[^'`echo -n '\0'`']*foo'

이 시점에서 나는 내 쉘이 0 byte 를 생성하고 있음을 확인했습니다 echo -n '\0'. 불행히도 인수가 전달되는 방식으로 인해 pgrep이 명령은 실제 ​​0바이트를 볼 때 패턴을 검색하는 것과 정확히 동일하게 작동합니다 pgrep -f '^[^'. 즉, 유효하지 않은 패턴 수신에 대한 오류가 발생합니다.

0바이트(또는 0바이트가 아닌 모든 바이트)를 참조하는 패턴을 어떻게 작성합니까?

답변1

pgrep -f프로세스에 의해 실행된 마지막 명령에 전달된 인수와 일치하는 SPC 문자열 연결입니다( /proc/pid/cmdlineLinux에서와 같이). NUL 문자는 포함되지 않습니다.

따라서 다음을 수행해야 합니다.

pgrep -f '^[^ ]*foo( |$)'

/path/with space/foo특정 명령을 실행하는 데 as를 사용하는 프로세스가 누락되더라도 argv[0]명령을 실행하는 데 as를 사용하는 프로세스는 보고됩니다.foo barargv[0]

명령 매개변수는 NUL로 구분된 문자열이므로 어떤 경우에도 매개변수의 NUL을 실행된 명령에 전달할 수 없습니다.

에서는 zsh내장 명령 및 함수에 NUL을 전달할 수 있습니다(이 제한의 영향을 받지 않기 때문입니다 execve().처형된). 따라서 Linux에서는 다음과 같이 할 수 있습니다.

print -rC1 /proc/<->(Ne[$'[[ "${$(<$REPLY/cmdline)%%\0*}" = *foo ]]']:t)

argv[0]로 끝나는 프로세스를 찾습니다 foo.

또는:

print -rC1 /proc/<->/exe(N-.e['[[ $REPLY:A = *foo ]]']:h:t)

경로 끝에서 명령을 실행하는 사용자를 위한 것입니다 foo(자신의 프로세스로 제한될 수도 있음).

Linux에서 프로세스 이름은 15바이트로 제한되며 호출할 때마다 첫 번째 인수 기본 이름의 처음 15바이트로 변경되지만 쓰기 또는 를 사용하여 변경할 execve()수도 있습니다 . 프로세스는 의 내용을 변경할 수도 있습니다 . 예를 들면 다음을 참조하세요./proc/pid/commprctl(PR_SET_NAME)/proc/pid/cmdline

$ perl -lne 'BEGIN{$0 = "foo bar 90123456789"}; print "$ARGV: $_"' /proc/self/{cmdline,comm}
/proc/self/cmdline: foo bar 90123456789
/proc/self/comm: foo bar 9012345

관련 정보