ゼロバイトと絶対に一致しないpgrepパターンを作成する方法は?

ゼロバイトと絶対に一致しないpgrepパターンを作成する方法は?

foo現在私の計画は、pkillテスト目的でプロセスに優しいスキーマを確認することですpgrep。私は見たこの問題これは長いプロセス名の場合です-f。これは、長いプロセス名の残りの部分を取得するのに役立ちます。問題は、パターンがプロセス名だけでなくコマンドライン全体と一致することですfoo。議論。

だから私は次のようなパターンを作成したいと思います。

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

これが意味するのは\00バイトです。つまり、-fプロセスの各引数の前に区切り文字が配置されます。もちろん\0そうではありません。パターンは、実際には\(ASCII)以外のすべての文字シーケンスと一致します0。私もこれを試しました:

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

この時点で、私のシェルがゼロバイトを生成していることを確認しましたecho -n '\0'。残念ながら、引数が渡される方法のため、pgrepこのコマンドは実際のゼロバイトを見るときにパターンを検索するのとまったく同じように機能しますpgrep -f '^[^'。つまり、無効なパターン受信にエラーが発生します。

ゼロバイト(またはゼロバイト以外のすべてのバイト)を参照するパターンをどのように作成しますか?

ベストアンサー1

pgrep -fプロセスによって実行された最後のコマンドに渡された引数と一致するSPC文字列連結(/proc/pid/cmdlineLinuxと同様)。 NUL 文字は含まれません。

したがって、次のことを行う必要があります。

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

/path/with space/foo特定のコマンドを実行するためにasを使用するプロセスが欠落していても、コマンドを実行するためにasを使用するargv[0]プロセスが報告されます。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

おすすめ記事