When I use below code in SSH terminal for CentOS it works fine:

paste <(printf "%s\n" "TOP")

But if I place the same line code in a shell script (test.sh) and run shell script from terminal, it throws error as this

./test.sh: line 30: syntax error near unexpected token ('   
./test.sh: line 30:     paste <(printf "%s\n" "TOP")

How can I fix this problem?

  • How exactly are you running it? what '#!' line (if any) starts your script? It looks like you are invoking a shell interpreter that doesn't support that syntax (e.g. dash instead of bash). – steeldriver Aug 24 '14 at 14:28
  • I have #!/bin/sh at the top. I executed as bash test.sh but it did not work either. – NecNecco Aug 24 '14 at 14:49
  • bash in POSIX mode doesn't support that syntax either (when called with --posix or as /bin/sh). Use #!/bin/bash. – jordanm Aug 24 '14 at 15:21
  • @NecNecco: Do you have POSIXLY_CORRECT variable set when you start bash? – cuonglm Aug 24 '14 at 15:31
  • @jordanm switching to #!/bin/bash at the top fixed the problem. – NecNecco Aug 24 '14 at 16:51

Process substitution is not specified by POSIX, so not all POSIX shell support it, only some shells like bash, zsh, ksh88, ksh93 support.

In Centos system, /bin/sh is symlink to /bin/bash. When bash is invoked with name sh, bash enters posix mode (Bash Startup Files - Invoked with name sh). In posix mode, process substitution is not supported, cause syntax error.

Script should work, if you call bash directly bash test.sh. If not, maybe bash has entered posix mode. This can be occur if you start bash with --posix argument or variable POSIXLY_CORRECT is set when bash start:

$ bash --posix test.sh 
test.sh: line 54: syntax error near unexpected token `('
test.sh: line 54: `paste <(printf "%s\n" "TOP")'

$ POSIXLY_CORRECT=1 bash test.sh 
test.sh: line 54: syntax error near unexpected token `('
test.sh: line 54: `paste <(printf "%s\n" "TOP")

Or bash is built with --enable-strict-posix-default option.

Here, you don't need process substitution, you can use standard shell pipes:

printf "%s\n" "TOP" | paste -

- is the standard way to tell paste to read the data from stdin. With some paste implementations, you can omit it though that's not standard.

Where it would be useful is when pasting the output of more than one command like in:

paste <(cmd1) <(cmd2)

On systems that support /dev/fd/n, that can be done in sh with:

{ cmd1 4<&- | { cmd2 3<&- | paste /dev/fd/3 -; } 3<&0 <&4 4<&-; } 4<&0

(it's what <(...) does internally).


Here's another workaround. Instead of running the command, run bash and pass the command to bash using -c:

bash -c 'paste <(printf "%s\n" "TOP")'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.