Command runs from the shell, but doesn't run from a script.sh

13,160

Solution 1

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).

Solution 2

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.

Share:
13,160

Related videos on Youtube

user2962151
Author by

user2962151

Updated on September 18, 2022

Comments

  • user2962151
    user2962151 over 1 year

    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

    • phemmer
      phemmer about 7 years
      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.
    • user2962151
      user2962151 about 7 years
      Thanks for your answer, Patrick. I supplemented the original post with the full script code and information about the environment.
    • wjandrea
      wjandrea about 7 years
    • Dmitry Grigoryev
      Dmitry Grigoryev about 7 years
      How come you have an error on line 16 in a 14-line script?
  • user2962151
    user2962151 about 7 years
    Patrick, Gilles, thanks a lot for solution!
  • Kusalananda
    Kusalananda about 7 years
    @user2962151 If this solves your issue, please consider accepting the answer. This additionally improves the chances of getting help in the future.
  • noNihongo
    noNihongo over 3 years
    It is very useful!