You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

命令在Shell中正常运行但在Bash脚本中报错的问题排查

问题:Bash脚本中无法使用扩展通配符匹配多后缀文件

问题场景

在交互式Bash环境中执行以下命令,能正常匹配指定后缀的文件:

$ ls files/@(*.text|*.txt|*.xt)
files/f1.text  files/f1.txt  files/f1.xt

但将命令写入Bash脚本后执行,却抛出文件不存在的错误。脚本内容如下:

#!/bin/bash

ls files # 此命令可正常执行
ls files/@\(*.text\|*.txt\|*.xt\) # 此命令执行失败

执行脚本后的输出:

$ ./testScript.sh 
files/f1.text  files/f1.txt  files/f1.xt
ls: cannot access files/@(*.text|*.txt|*.xt): No such file or directory

尝试多种写法均未解决:

  • 直接写ls files/@(*.text|*.txt|*.xt):报语法错误line 4: syntax error near unexpected token '('
  • 转义写法ls files/@\(*.text|*.txt|*.xt\):报line 4: *.xt): command not found
  • 用sh ./testScript.sh执行:报错与原问题一致
  • 使用绝对路径/files/@(*.text|*.txt|*.xt):仍报错

已确认当前默认Shell为Bash:

$ echo $SHELL
/bin/bash

原因分析

@(...)属于Bash的扩展通配符(extglob)特性,该特性默认在交互式Shell中开启,但在**非交互式Shell(即脚本运行环境)**中默认关闭。因此脚本中直接使用该语法时,Bash会将@(*.text|*.txt|*.xt)当作普通字符串处理,导致ls无法找到对应文件。此外,若用sh执行脚本,由于sh本身不支持extglob特性,同样会报错。

解决方案

方法1:在脚本中开启extglob特性

在脚本开头添加shopt -s extglob命令,开启扩展通配符支持,之后直接使用原命令即可,无需转义:

#!/bin/bash
shopt -s extglob

ls files
ls files/@(*.text|*.txt|*.xt)

方法2:使用其他替代匹配方式

如果不想依赖extglob特性,可改用以下方式实现相同效果:

  • 多个通配符直接组合:
    ls files/*.text files/*.txt files/*.xt
    
  • 使用find命令(适合更复杂的匹配场景):
    find files -maxdepth 1 -type f \( -name "*.text" -o -name "*.txt" -o -name "*.xt" \)
    

内容的提问来源于stack exchange,提问作者Ammar Hussein

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 22:40:37