![0바이트와 절대 일치하지 않는 pgrep 패턴을 작성하는 방법은 무엇입니까?](https://linux55.com/image/180607/0%EB%B0%94%EC%9D%B4%ED%8A%B8%EC%99%80%20%EC%A0%88%EB%8C%80%20%EC%9D%BC%EC%B9%98%ED%95%98%EC%A7%80%20%EC%95%8A%EB%8A%94%20pgrep%20%ED%8C%A8%ED%84%B4%EC%9D%84%20%EC%9E%91%EC%84%B1%ED%95%98%EB%8A%94%20%EB%B0%A9%EB%B2%95%EC%9D%80%20%EB%AC%B4%EC%97%87%EC%9E%85%EB%8B%88%EA%B9%8C%3F.png)
foo
현재 내 계획은 pkill
테스트 목적으로 프로세스 친화적으로 스키마를 확인하는 것 입니다 pgrep
. 나는 보았다이 문제이는 긴 프로세스 이름의 경우 -f
. 이는 긴 프로세스 이름의 나머지 부분을 얻는 데 유용합니다. 문제는 패턴이 프로세스 이름뿐만 아니라 전체 명령줄과 일치한다는 것입니다 foo
. 논쟁.
그래서 저는 다음과 같은 패턴을 작성하고 싶습니다.
pgrep -f '^[^\0]*foo'
이것이 의미하는 바는 \0
0바이트입니다. 즉, -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/cmdline
Linux에서와 같이). NUL 문자는 포함되지 않습니다.
따라서 다음을 수행해야 합니다.
pgrep -f '^[^ ]*foo( |$)'
/path/with space/foo
특정 명령을 실행하는 데 as를 사용하는 프로세스가 누락되더라도 argv[0]
명령을 실행하는 데 as를 사용하는 프로세스는 보고됩니다.foo bar
argv[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/comm
prctl(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