在bash中的变量值内部展开“*”

在bash中的变量值内部展开“*”,bash,Bash,我是否可以创建一个值中带有*的bash变量,然后在使用时由shell扩展该* 例如 这是作为cron作业的一部分运行的,我在电子邮件中收到一个错误,上面说: mv: cannot stat `/path/*.phtml*': No such file or directory 因此,在我看来,*没有展开,可能只有在它没有找到任何匹配项时才展开。正确:没有匹配项时,不展开是默认行为 这让 ls *.txt 返回类似于的错误 ls: no file '*.txt' found 而不是退回到列出

我是否可以创建一个值中带有
*
的bash变量,然后在使用时由shell扩展该
*

例如

这是作为cron作业的一部分运行的,我在电子邮件中收到一个错误,上面说:

mv: cannot stat `/path/*.phtml*': No such file or directory

因此,在我看来,
*
没有展开,可能只有在它没有找到任何匹配项时才展开。

正确:没有匹配项时,不展开是默认行为

这让

ls *.txt
返回类似于的错误

ls: no file '*.txt' found
而不是退回到列出所有文件的默认行为(如果没有参数的话)


如果要计算为空列表,请使用:

shopt -s nullglob
…或只是检查是否存在任何结果:

for f in $sourcefiles; do
  [[ -e $f ]] || continue
  echo "Found file named: $f";
  mv "$f" /other/path/"$f"
  ((++filesfound))
done
或者,考虑:

shopt -s nullglob
sourcefiles=( /path/*.phtml* )
filesfound=${#sourcefiles[@]}

# print entire list, with names quoted to make hidden characters &c readable
printf 'Found file named: %q\n' "${sourcefiles[@]}"

# warning: this only works if the list is short enough to fit on one command line
mv -- "${sourcefiles[@]}" /other/path/

正确:没有匹配项时,不展开是默认行为

这让

ls *.txt
返回类似于的错误

ls: no file '*.txt' found
而不是退回到列出所有文件的默认行为(如果没有参数的话)


如果要计算为空列表,请使用:

shopt -s nullglob
…或只是检查是否存在任何结果:

for f in $sourcefiles; do
  [[ -e $f ]] || continue
  echo "Found file named: $f";
  mv "$f" /other/path/"$f"
  ((++filesfound))
done
或者,考虑:

shopt -s nullglob
sourcefiles=( /path/*.phtml* )
filesfound=${#sourcefiles[@]}

# print entire list, with names quoted to make hidden characters &c readable
printf 'Found file named: %q\n' "${sourcefiles[@]}"

# warning: this only works if the list is short enough to fit on one command line
mv -- "${sourcefiles[@]}" /other/path/


为什么您认为您的代码没有这样做?顺便说一句,所有caps变量名都是为shell和系统实用程序提供或使用的变量保留的——您应该为自己的变量使用小写或混合大小写的名称。请参阅的第四段中的相关规范,记住shell和环境变量共享一个名称空间…这就是为什么实际上更倾向于将值存储在变量中,而不是存储模式:
sourcefiles=(/path/*.phtml*)
创建一个名为
sourcefiles
的数组,该数组可以扩展到所有与
“${sourcefiles[@]}”
匹配的文件。警告:如果没有匹配的文件,数组将包含模式本身,除非启用了
nullglob
选项。顺便说一句,在数学上下文中不需要
$
运算符;只要
(++varname))
就可以了。(为了理解为什么这比
((varname++)
)更可取,请参见BashFAQ 105:@nortally中的一些示例,bash中的“去引用”通常指间接引用——一种非常不同的操作,具有非常不同的语法(而且,从Bash4.3开始,可以通过采用ksh的namevars获得)。为什么您认为您的代码没有这样做?顺便说一句,所有caps变量名都是为shell和系统实用程序提供或使用的变量保留的——您应该为自己的变量使用小写或混合大小写的名称。请参阅的第四段中的相关规范,记住shell和环境变量共享一个名称ce…这就是为什么实际上更喜欢将值存储在变量中而不是存储模式:
sourcefiles=(/path/*.phtml*)
创建一个名为
sourcefiles
的数组,该数组可以扩展到所有匹配的文件,并使用
“${sourcefiles[@]}”
.Caveat:如果没有匹配的文件,数组将包含模式本身,除非启用了
nullglob
选项。顺便说一句,在数学上下文中不需要
$
运算符;只需
(++varname))
即可。(为了理解为什么这比
((varname++)更可取)
,请参见BashFAQ#105中的一些示例:@nortally,bash中的“取消引用”通常指间接引用——一种非常不同的操作,具有非常不同的语法(而且,从bash 4.3开始,通过采用ksh的名称变量提供).那么也许我真的没有问题,只是没有匹配。但是我在“文件发现”中得到了一个假阳性variable.Short-circuit循环当返回一个不存在的项时将解决这个问题…请参阅我的示例中的
| | continue
。我现在就测试这个问题,可能会通过复选标记和向上投票返回给您。我还将使用
sourcefiles=(/path/*.phtml*)进行尝试
如果你想知道第二条路径更好的具体原因,看看如果你的目录名中有空格会发生什么——当它是硬编码的bash语法时,你可以引用/转义这个名称,但在扩展中你不能这样做——请看BashFAQ#50——因此需要清除IFS以防止字符串分裂,这是一个副作用的操作嗯,也许我真的没有问题,只是没有匹配。但是我在“文件发现”中得到了一个假阳性variable.Short-circuit循环当返回一个不存在的项时将解决这个问题…请参阅我的示例中的
| | continue
。我现在就测试这个问题,可能会通过复选标记和向上投票返回给您。我还将使用
sourcefiles=(/path/*.phtml*)进行尝试
如果您想知道第二条路径更好的具体原因,请看看如果目录名中有空格会发生什么情况——当名称是硬编码的bash语法时,您可以引用/转义名称,但在扩展中不能这样做——请参见BashFAQ#50——因此需要清除IFS以防止字符串拆分,这是一种副作用的操作。