Cpt. Senkfuss Cpt. Senkfuss - 1 month ago 11
Linux Question

Doesn't sh support process substitution <(...)?

On a Centos 6 machine, this works:

bash -c 'if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'


and this doesn't:

sh -c 'if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'


I get:

sh: -c: line 0: syntax error near unexpected token `('
sh: -c: line 0: `if grep -qP --line-buffered ".+" <(tail -n 1000 -F catalina.out) ; then echo "yes"; fi'


Nevermind the grep and tail. The problem is with the process substitution thingy:
<(...)


Can someone tell me what sh does differently here?

[EDIT]

Thanks for the answers!

The problem arose while using capistrano for deployments. It defaults to using sh but I changed that to bash now.
The reason I couldn't do the normal piping is that when using
tail -F | grep -q --line-buffered
, grep won't exit immediately after a match. There has to be one more edit to the file like
echo "" >> catalina.out
and this was not acceptable in my situation.

Answer

The syntax <(...) is only supported by BASH.

For any POSIX shell, use this approach:

sh -c 'tail -n 1000 -F catalina.out | if grep -qP --line-buffered ".+" ; then ...'

i.e. move the stdin redirection in front of the if with a pipe. The if will pass stdin on to the grep.

if tail ...| grep won't work since the if won't be able to see it's then/fi because the pipe separates processes.