Shell脚本执行diff进程替换命令报syntax error near unexpected token '('
问题场景
在CentOS系统环境下操作时遇到如下现象:
- 在
/etc/sysconfig/network-scripts目录下手动执行第一条命令,输出如下:
[root@vmc-centos network-scripts]# ls -ltr | grep -oh "\w*ifcfg-ens3\w*" | grep -oh "\w*ens3\w*" | sort --unique ens32 ens33 ens34
- 手动执行第二条命令,输出如下:
[root@vmc-centos network-scripts]# ip link show | grep -oh "\w*ens3\w*" ens32 ens33
- 在交互式命令行直接执行基于进程替换语法
<()的diff对比命令,可正常返回结果ens34,执行命令为:
diff <(ls -ltr | grep -oh "\w*ifcfg-ens3\w*" | grep -oh "\w*ens3\w*" | sort --unique) <(ip link show | grep -oh "\w*ens3\w*") | sed -n 2p
- 将上述命令写入Shell脚本
rundiffer.sh,脚本内容如下:
[root@vmc-centos tmp]# vi rundiffer.sh cd /etc/sysconfig/network-scripts/ result=$(diff <(ls -ltr | grep -oh "\w*ifcfg-ens3\w*" | grep -oh "\w*ens3\w*" | sort --unique) <(ip link show | grep -oh "\w*ens3\w*") | sed -n 2p) echo $result
执行sh rundiffer.sh运行脚本时抛出如下错误:
rundiffer.sh: command substitution: line 3: syntax error near unexpected token `(' rundiffer.sh: command substitution: line 3: `diff <(ls -ltr | grep -oh "\w*ifcfg-ens3\w*" | grep -oh "\w*ens3\w*" | sort --unique) <(ip link show | grep -oh "\w*ens3\w*") | sed -n 2p)'
错误产生原因
- 进程替换语法
<()是Bash专属特性,不属于POSIX Shell标准语法。CentOS系统中sh命令默认指向POSIX兼容Shell(通常为dash或POSIX运行模式的bash),不支持该语法,执行时会将<识别为重定向符号,把后续的(判定为非法语法标记,最终抛出语法错误。 - 系统交互式命令行默认调用bash解释器,原生支持进程替换特性,因此直接在命令行执行相同命令不会触发报错。
可行修复方案
- 方案1:指定bash解释器执行脚本
放弃使用sh rundiffer.sh的执行方式,改用bash rundiffer.sh运行脚本,直接调用支持进程替换特性的bash解释器即可正常执行。 - 方案2:添加脚本解释器声明
在rundiffer.sh文件的最开头添加shebang声明头:
随后执行#!/bin/bashchmod +x rundiffer.sh给脚本添加可执行权限,通过./rundiffer.sh方式运行时,系统会自动调用声明的bash解释器执行脚本,无需手动指定解释器。 - 方案3:改写命令兼容POSIX Shell
如果必须使用sh执行脚本,可以避开进程替换语法,通过临时文件存储中间对比结果,改写后的脚本内容如下:cd /etc/sysconfig/network-scripts/ tmp1=$(mktemp) tmp2=$(mktemp) ls -ltr | grep -oh "\w*ifcfg-ens3\w*" | grep -oh "\w*ens3\w*" | sort --unique > "$tmp1" ip link show | grep -oh "\w*ens3\w*" > "$tmp2" result=$(diff "$tmp1" "$tmp2" | sed -n 2p) rm -f "$tmp1" "$tmp2" echo $result
内容的提问来源于stack exchange,提问作者Vijay Kumar R
相关产品推荐
相关产品推荐

