Conditional execution is used in Bash to control the flow of a script on the basis of the exit status of a subprocess. However, there are situations when a subprocess (application) is launched in the background, to be used for interactive purposes, so there is no exit and no exit status, until it is closed.
Consider some examples, say launching a pdf viewer, mupdf. Consider the first case with a file that exists, example.pdf:
$ mupdf example.pdf &  16220
That works, so let's try conditional execution:
$ mupdf example.pdf & && echo TRUE bash: syntax error near unexpected token '&&'
Hmmm. Ok, let's try another (contrived) way, trying to avoid errors:
$ if mupdf example.pdf &; then echo TRUE; fi bash: syntax error near unexpected token ';'
$ if (mupdf example.pdf &); then echo TRUE; fi TRUE
That looks promising, But then we try the second case, with a file that does not exist:
$ mupdf nofile.pdf &  16282 $ error: cannot open nofile.pdf error: cannot load document 'nofile.pdf' mupdf: error: cannot open document $ if (mupdf nofile.pdf &); then echo TRUE; fi TRUE $ error: cannot open nofile.pdf error: cannot load document 'nofile.pdf' mupdf: error: cannot open document
That construct is not working either. So the usual approach to conditional execution does not work because there is no exit status. But I noted that a pid is initially created in both successful and unsuccessful cases (mupdf does not open in the second case - launching ultimately fails).
So try another approach, wait to see what happens with the background pid, so we put together the following script:
#!/usr/bin/env bash # usage: ./show <file>.pdf mupdf "$1" &>/dev/null & sleep 2 if kill -0 $! &>/dev/null then echo TRUE else echo FALSE fi # end file
And test the first case:
$ ./show example.pdf # case 1  16602 TRUE
That's OK. Now the second case:
$ ./show nofile.pdf # case 2  16699 + Exit 1 mupdf nofile.pdf &> /dev/null FALSE
Well that works too. But this seems a very convoluted way to check the process and may fail if the launch takes more time (more than 2 seconds). So my question becomes, is there a better (cleaner) way to solve this problem?