Baby processes in bash

We use bash scripts with asynchronous calls using '&'. Something like that:

function test() {
   sleep 1
} 
test &
mypid=$!
# do some stuff for two hours
wait $mypid 

Usually everything is fine, but sometimes we get an error

"wait: pid 419090 is not a child of this shell"

I know that bash stores child pids in a special table, and I know ("people are waiting") that bash is allowed not to store status information in this table if no one uses $ !, and no one can specify 'wait $ mypid '. I suspect that this optimization contains an error that causes the error. Does anyone know how to print this table or how to disable this optimization?

+4
source share
2 answers

- , , fork 2 .

pids, , ( ).

bash (1) , , .

, .

0

gdb , . yum install bash-debuginfo. gdb .

(gdb) b wait_for_single_pid
Breakpoint 1 at 0x441840: file jobs.c, line 2115.
(gdb) c
Continuing.

Breakpoint 1, wait_for_single_pid (pid=11298) at jobs.c:2115
2115    {
(gdb) n
2120      BLOCK_CHILD (set, oset);
(gdb)
2121      child = find_pipeline (pid, 0, (int *)NULL);
(gdb) s
find_pipeline (pid=pid@entry=11298, alive_only=alive_only@entry=0, jobp=jobp@entry=0x0) at jobs.c:1308
1308    {
(gdb)
1313      if (jobp)
(gdb) n
1315      if (the_pipeline)
(gdb)
1329      job = find_job (pid, alive_only, &p);
(gdb) s
find_job (pid=11298, alive_only=0, procp=procp@entry=0x7ffdc053f038) at jobs.c:1364
1364      for (i = 0; i < js.j_jobslots; i++)
(gdb) n
1372          if (jobs[i])
(gdb)
1374              p = jobs[i]->pipe;
(gdb)
1378                  if (p->pid == pid && ((alive_only == 0 && PRECYCLED(p) == 0) || PALIVE(p)))
(gdb)
1385                  p = p->next;
(gdb)
1387              while (p != jobs[i]->pipe);

pipe, jobs. , , , .

0

Source: https://habr.com/ru/post/1626526/


All Articles