[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-bash] Problems with background jobs

From: R. Diez
Subject: [Help-bash] Problems with background jobs
Date: Thu, 16 Aug 2018 10:52:32 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.9.1

Hi there:

I am trying to implement a solution to this problem:

But the exact problem is not relevant. It is about coordinating processes with pipes.

Ideally, I would do it with a Bash script like this:

1) Create an unnamed pipe, like 'coproc' does, but leaving stdin and stdout untouched.

2) Start the OpenOCD process as a background job.

3) Wait for my OpenOCD script to write to the pipe, so that I know that OpenOCD is now ready to accept connections.

If OpenOCD dies during initialisation, reading from the pipe will fail, and the Bash script will exit.

4) Start GDB in the foreground, which connects to OpenOCD. The Bash script will continue when GDB exits.

5) Wait for the OpenOCD background job to finish. We do not want to leave zombie processes behind.

6) Exit with OpenOCD's exit code.

Problem 1: I could not do it like that because apparently Bash cannot create an unnamed pipe leaving stdin and stdout untouched. There are non-portable, ugly work-arounds, which I would try to avoid.

The next approached I tried was to create a named pipe with mkfifo, and pass its name to my OpenOCD script. But then, if OpenOCD fails, my Bash script will forever hang reading from the FIFO.

So I tried writing a loop:

- While true:

Step 1) Read from the FIFO with timeout. If something was read, break out of the loop.

Step 2) Check whether the OpenOCD child process is still alive. If it is dead, it will never write to the FIFO.

By the way, Bash does not document that opening such a FIFO as "read only" hangs (at least on Linux). But I found out that, when opening as read/write, it does work.

The problem is now how to find out whether the child process still lives, and what it exit code was.

Problem 2: There does not seem to be a way to grab the last job ID.

Using %% is dangerous, because something else could start another background job and overwrite it.

Using a %string is difficult, because these are long commands with possibly sell-quoted filepaths inside. I am not sure which part of the command string I should take.

Problem 3: The "kill -0 $pid" work-around is not safe, because process IDs can be recycled. I guess using a Bash job spec is safer.

Problem 4: "wait %%" hangs, as it has no timeout option, so I cannot use it in the loop.

Problem 5: I could use "jobs %%" to see if the job if still alive. But extracting the process exit code is hard. If the process has died in the meantime, "jobs %%" will fail with "no such job", and then "wait %%" will also fail with "no such job", instead of returning the exit status.

I am a little confused by "jobs". When "jobs %%" reports a job as finished like this:

[1]+  Done          

Has it then removed the job, so that it is no longer available for "wait %%"?

Is it safe to parse the output from "jobs"? The exact format is not documented (exit status, killed by signal, ...). Should I assume that the text format can change in the future?

Thanks in advance for any help in this regard,

reply via email to

[Prev in Thread] Current Thread [Next in Thread]