命令在终端中有效,但在 bash 脚本中无效

命令在终端中有效,但在 bash 脚本中无效

如果我想删除当前目录中除“myfile”之外的所有内容,我可以使用

rm -r !("myfile")

但是如果我把它放在一个脚本中(称为cleanup):

#!/bin/bash
rm -r !("myfile")

我得到:

pi@raspberrypi:~/tmp $ ./cleanup
./cleanup: line 2: syntax error near unexpected token `('
./cleanup: line 2: `rm -r !("file2")'

如果我跑

ps -p $$

我可以看到我的终端正在使用 bash,

 PID TTY          TIME CMD
1345 pts/3    00:00:02 bash

所以我不清楚问题是什么。


笔记:

  1. 我意识到如果该脚本实际上有效,它会自行删除。所以,我的脚本实际上更像是:rm -r !("cleanup"|"myfile"),但错误消息是相同的。
  2. 如块引用所示,这是基于 Debian 的 Raspbian 操作系统(9 -stretch)。
  3. 我觉得这个问题肯定是重复的,但我找不到它。有一个类似名字的问题,但它是关于继承变量的,所以不能解决我的问题。

答案1

该模式是一个!(pattern-list)扩展全局。许多发行版都为交互式 shell 启用了它,但不为非交互式 shell 启用它。你可以检查一下

$ shopt extglob
extglob         on
$ bash -c 'shopt extglob'
extglob         off

要修复您的脚本,您必须将其打开:添加

shopt -s extglob

在它的开始。

答案2

您在这里使用的是扩展的通配符功能。

从 bashman页面:

If  the  extglob shell option is enabled using the shopt builtin, several extended pattern
matching operators are recognized.  In the following description, a pattern-list is a list
of  one  or more patterns separated by a |.  Composite patterns may be formed using one or
more of the following sub-patterns:   

[...]

       !(pattern-list)
              Matches anything except one of the given patterns

这个可以通过命令控制的 shell 选项shopt在交互式 shell 中默认启用,但在非交互式 shell(脚本)中默认禁用。

要启用它,请使用shopt -s extglob.

相关内容