web-dev-qa-db-ja.com

コマンドはシェルから実行されますが、script.shからは実行されません

パイプとファイルの2つのソースからjoinを作成しようとしています。私はこのシンプルなワンライナーを書きました:

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

通常はシェルから実行されますが、script.shからは実行されません(完全なスクリプトは以下を参照)。

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

式内で異なる引用符を使用して変数、パラメーター、またはコマンドを完全にマスクしようとしましたが、スクリプトを実行できませんでした。

誰か助けてもらえますか?

P. S.このスクリプトは、macOS Sierra 10.12.3のGeekTool(シェルウィジェット)によって呼び出されます。

P.P.S.はい、OS Xが「Unix&Linux」ではないことは知っていますが、違いはそれほど大きくないと思いました。

コメント付きの完全なスクリプトは次のとおりです。

#!/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}'

更新しました。解決済み

シバンは#!/bin/bashに変更されました

1
user2962151

スクリプトの実行に使用しているシェルがインタラクティブシェルと同じではないため、ほぼ確実にこれが発生しています。

シバンの行は_#!/bin/sh_であるため、スクリプトはインタープリター_/bin/sh_によって実行されます。 Ubuntuなどのディストリビューションでは、_/bin/sh_はダッシュシェルであり、プロセス置換(<()ビット)など、bashが行うすべての機能をサポートしているわけではありません。

解決策は、_/path/to/bash /path/to/script_を使用してスクリプトを呼び出すか、Shebang行(_#!/path/to/bash_)を修正します。

15
Patrick

このスクリプトは、<(...)構文で示されるbash固有の機能 process-substitution を利用しています。 ( Advanced Bash-Scripting Guide も参照してください)。

そのbashismを排除するには、問題のある行を次のように再配置します。

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

に:

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

これにより、/ bin/shで実行したときにそのエラーが解消されます。

5
ovirt