1

例:

$ cat main.sh
#!/bin/bash
./child_level1.sh &

$ cat child_level1.sh
#!/bin/bash
./child_level2.sh &

$ cat child_level2.sh
#!/bin/bash
echo Hi, fork()s! &

$ ./main.sh # outputs Hi, fork()s

ターゲット: $1 を実行し、すべてのフォークの pid を収集するスクリプトfollow.shを作成します。そのように:

$ ./follow.sh ./main.sh
[pid_main.sh] [pid_child_level1.sh] [pid_child_level2.sh] [pid_of_echo]

その例では4つの数字)。しばらくしてから数字が表示される場合があります。pidtracerのようなユーティリティfollow.shの既知の名前があるのでしょうか?

4

4 に答える 4

1

この変数$!は、バックグラウンドで実行した最新のコマンドの PID を示します。echo $!そのため、各バックグラウンド コマンドをすぐに実行してみてください。

于 2013-03-01T14:18:05.150 に答える
1

@tripleee に感謝します。良い解決策だと思います。

$ cat ./wrap_fork.c
//fork wrapper.c
#include <dlfcn.h>
#include <stdio.h>
#include <unistd.h>

pid_t fork(void){
  FILE * f = fopen("/tmp/dearforks","a");
  typedef pid_t (*t_fork)(void);
  t_fork org_fork = dlsym(((void *) -1l), "fork");
  pid_t p = org_fork();
  fprintf(f,"pid = %i\n",p);
  fclose(f);
  return p;
}

$ gcc -fPIC -c -Wall wrap_fork.c
$ gcc -shared wrap_fork.o -ldl -lstdc++ -o wrap_fork.so

follow.sh

$ cat follow.sh
#!/bin/bash
export LD_PRELOAD=./wrap_fork.so
$* &

さあ、実行の時間です:

./follow.sh ./main.sh

そして結果:

$ cat /tmp/dearforks
pid = 2065
pid = 0
pid = 2066
pid = 0
pid = 2067
pid = 0

それは私が欲しいものの味を持っています。いくつかのゼロを除いて) (そして、後でsleepを呼び出した後の pid :( )

結果にゼロがあるのはなぜですか?

于 2013-03-04T18:12:35.903 に答える
1

名前が環境変数に保存されている一時ファイルを使用した簡単なソリューションを次に示します。

$ cat main.sh
#!/bin/bash
export mytrace="pids-from-$$.tmp"
echo $$ >| "$mytrace"
./child_level1.sh &

$ cat child_level1.sh
#!/bin/bash
echo $$ >> "$mytrace"
./child_level2.sh &

$ cat child_level2.sh
#!/bin/bash
echo $$ >> "$mytrace"
echo -n "The pids are: "
tr \\n ' ' < "$mytrace"
echo
rm -f "$mytrace"
于 2013-03-01T17:08:13.570 に答える
0

スクリプトの終了が速すぎるため、すべての pid を見つけることはできません。それらが十分に長く実行される場合は、使用できます

ps axo ppid,pid,comm

すべてのプロセスの親 pid、スクリプト pid、およびコマンド名を取得します。次に、最初のスクリプト pid から始まるツリーを構築できます$!

于 2013-03-01T14:37:07.310 に答える