命令从 shell 运行,但不从 script.sh 运行

命令从 shell 运行,但不从 script.sh 运行

我尝试join从两个来源创建 a:管道和文件。我写了这么简单的一句话:

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

它通常从 shell 运行,但不是从 script.sh 运行(完整脚本见下文):

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

我尝试在表达式中使用不同的引号来完全屏蔽变量、参数或命令,但我无法运行该脚本。

有人可以帮忙吗?

PS 该脚本由 macOS Sierra 10.12.3 上的 GeekTool(Shell 小部件)调用。

PPS 是的,我知道 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

几乎可以肯定会发生这种情况,因为您用来运行脚本的 shell 与交互式 shell 不同。

由于 shebang 行是#!/bin/sh,因此您的脚本由解释器执行/bin/sh。在 Ubuntu 等发行版上,/bin/sh有 dash shell,它不支持 bash 的所有功能,例如进程替换(这<()一点)。

解决方案是使用 调用脚本/path/to/bash /path/to/script,或者修复 shebang 行 ( #!/path/to/bash)。

答案2

该脚本利用了 bash 特定的功能,流程替代,由语法表示<(...)。 (也可以看看高级 Bash 脚本指南)。

为了消除那个巴什主义您可以重新排列有问题的行:

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 执行时的错误。

相关内容