1

I try to make a join from two sources — from a pipe and a file. I wrote this simple one-liner:

FILENAME=$TMPDIR".netstat"; \
join -t , $FILENAME <(nettop -t wifi -P -x -L1 | cut -d , -f 2,5,6 | tail -n +2) | \
awk '{print $0}'

It normally runs from the shell, but it doesn't run from a script.sh (full script see below):

./script.sh: line 16: syntax error near unexpected token `('

I tried to use different quotes inside my expression to mask variables, parameters or commands entirely, but I could not run the script.

Can anybody help?

P. S. This script is invoking by GeekTool (Shell widget) on macOS Sierra 10.12.3.

P.P.S. Yes, I know that OS X is not "Unix & Linux", but I thought the difference is not so great.

Full script with some comments is:

#!/bin/sh

FILENAME=$TMPDIR".netstat"

# checking if existing stats file
if [ ! -f $FILENAME ]; then
    nettop -t wifi -P -x -L 1 | cut -d , -f 2,5,6 | tail -n +2 > $FILENAME # save stats to file
    exit
fi

fts=`stat -r $FILENAME | cut  -d " " -f 10` # get timestamp of stats file
now=`date +%s`    # get current datetime

join -t, $FILENAME <(nettop -t wifi -P -x -L1 | cut -d , -f 2,5,6 | tail -n +2) | awk '{print $0}'

UPDATED. SOLVED

Shebang changed to #!/bin/bash

  • 3
    When asking questions like this, you should specify how you're calling the script, and the entire contents of the script. If you can't paste the whole script, strip it down into a minimal reproducible example. – Patrick Mar 26 '17 at 21:52
  • Thanks for your answer, Patrick. I supplemented the original post with the full script code and information about the environment. – user2962151 Mar 26 '17 at 22:39
  • 2
    macOS is Unix. – wjandrea Mar 27 '17 at 1:30
  • How come you have an error on line 16 in a 14-line script? – Dmitry Grigoryev Mar 27 '17 at 10:19
15

Almost certainly this is happening because the shell you are using to run the script is not the same as your interactive shell.

Since the shebang line is #!/bin/sh, your script is executed by the interpreter /bin/sh. On distros such as Ubuntu, /bin/sh is the dash shell, which does not support all the features bash does, such as process substitution (that <() bit).

The solution, either call the script with /path/to/bash /path/to/script, or fix the shebang line (#!/path/to/bash).

  • Patrick, Gilles, thanks a lot for solution! – user2962151 Mar 27 '17 at 5:35
  • 1
    @user2962151 If this solves your issue, please consider accepting the answer. This additionally improves the chances of getting help in the future. – Kusalananda Mar 27 '17 at 6:25
5

The script is utilising a bash-specific feature, process-substitution, indicated by the <(...) syntax. (See also Advanced Bash-Scripting Guide).

To eliminate that bashism you could rearrange the problematic line from:

join -t, $FILENAME <(nettop -t wifi -P -x -L1 | cut -d , -f 2,5,6 | tail -n +2)

to:

nettop -t wifi -P -x -L1 | cut -d , -f 2,5,6 | tail -n +2 | join -t, $FILENAME -

which would eliminate that error when executing it with /bin/sh.

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.