如何在bash脚本中使用带有getopts的通配符?

如何在bash脚本中使用带有getopts的通配符?,bash,getopts,Bash,Getopts,我有一个bash脚本,我想获取一些可选的输入参数,后跟一个文件名或一个包含通配符的文件规范 如果我跑 getopts\u problem.sh-td*.txt 该脚本会输出当前目录中的.txt文件列表: 文件为readme.txt letter_to_editor.txt someotherfile.txt 如果我运行getopts\u problem.sh-td*.ABC 脚本输出 文件是*.ABC 当前目录中没有扩展名为“.ABC”的文件。由于某种原因,脚本将“*.ABC”解释为文件名。如何

我有一个bash脚本,我想获取一些可选的输入参数,后跟一个文件名或一个包含通配符的文件规范

如果我跑
getopts\u problem.sh-td*.txt
该脚本会输出当前目录中的.txt文件列表:

文件为readme.txt letter_to_editor.txt someotherfile.txt

如果我运行
getopts\u problem.sh-td*.ABC
脚本输出

文件是*.ABC

当前目录中没有扩展名为“.ABC”的文件。由于某种原因,脚本将“*.ABC”解释为文件名。如何让脚本将“*.ABC”识别为要扩展的文件名表达式,而不是实际的文件名?代码如下:

# !/bin/sh
doDry=0
doTimestamp=0

while getopts ":dt" OPT;
do
   case $OPT in
      d ) doDry=1 ;;
      t ) doTimestamp=1 ;;
      ? ) echo 'Bad options used. '
          exit 1 ;;
    esac
done

shift $(($OPTIND - 1))
fileList=$@

for file in "$fileList"
do
  echo file is $file
done

exit 0

在执行脚本之前,通过
bash
扩展通配符模式。不是解释脚本的shell,而是从中运行脚本的shell。它是否保持模式、不通过任何操作还是失败取决于
nullglob
failglob
和一些类似的选项(请参见
manbash


此外,在“$fileList”中的文件的
中,引号明确告诉shell不要展开变量。

语义诡辩的可能重复:双引号允许变量展开(即用其值替换其名称),但防止分词(即根据空格将其拆分为多个单词)。净结果:循环只运行一次,
$file
设置为整个文件列表。解决方案是使用数组:
fileList=(“$”);对于“${fileList[@]}”中的文件--即使某些文件名包含空格或其他“有趣”字符,也会正确地打断文件列表。关于$fileList的引号,您是对的。我把它们拿出来,现在有三行“file is”输出,分别列出每个.txt文件。但它仍然认为“*.ABC”是一个文件名,这是一个问题。我提出的解决方法是在代码体中使用
[-e$file]
来测试文件是否存在。我不知道这是一种被接受的方式还是一种巨大的混乱,但它确实有效。@Kevin,就像我说的,不匹配任何文件的通配符的扩展由nullglob控制,请在bash手册页中查找它。还要记住,除非引用它,否则它将由用于启动脚本的shell处理。记住这一点。但是您也说过扩展发生在运行脚本的shell中。这是否意味着,如果要使用nullglob控制扩展,我必须在运行脚本之前在命令行上设置nullglob?是的,通常可执行文件会验证传递的文件,而不管其来源如何。我知道你不希望用户设置nullglob,我不是说提出这样的请求真的很酷,我只是解释了事情的本质;)