首页 > 解决方案 > BASH 变量,受数字文件和文件夹名称影响的命令

问题描述

问题

在包含数字编号的文件和文件夹的文件夹中运行 Linux 命令时,我遇到了问题;例如,文件顺序编号为 1、2、3 ...

例如,如果我所在的文件夹包含一个文件或文件夹,该文件或文件夹具有出现在我的命令中的数字名称,则该命令输出的输出可能会被截断。

这里有些例子:

$ ls -l
total 8
drwxr-xr-x 2 victoria victoria 4096 May  7 18:34 1
drwxr-xr-x 2 victoria victoria 4096 May  7 18:14 2
-rw-r--r-- 1 victoria victoria    0 May  7 18:34 3

## fail
$ a="[CPT1A] A Selective"; echo $a
1 A Selective
$ b="[CPT2A] A Selective"; echo $b
2 A Selective
$ c="[CPT3A] A Selective"; echo $c
2 A Selective
...

## pass
$ d="[CPT4A] A Selective"; echo $d
[CPT4A] A Selective

更新/解决方案

...每个接受的答案:使用时引用 BASH 变量。

$ a="[CPT1A] A Selective"; echo $a
1 A Selective
$ a="[CPT1A] A Selective"; echo "$a"
[CPT1A] A Selective

标签: bash

解决方案


问题是你在使用变量时没有引用它——也就是说,你使用echo $a的是echo "$a". 当一个变量被不带引号引用时,它被分割成单词(所以“[CPT1A] A Selective”变成了“[CPT1A]”“A”“Selective”),然后每个单词都包含任何看起来像文件名的东西通配符被扩展为匹配文件名的列表。

类似的方括号表达式[CPT1A]实际上是匹配其中任何单个字符的有效通配符表达式,因此如果有名为“A”、“C”、“P”、“T”或“1”的文件,它将扩展为匹配的名称。如果没有,通配符表达式就会完整地通过。

解决方案:双引号变量引用以避免这样的意外。$( )使用(或反引号,但不要使用它们)的命令替换也是如此。有一些地方可以安全地将它们关闭,例如在直接分配中,但 IMO 只是在任何地方使用它们比尝试跟踪异常更安全。例如,a=$b没问题,但也是a="$b"。另一方面,export a=$b可能会或可能不会工作(取决于您使用的外壳),但export a="$b" 工作。

顺便说一句,shellcheck.net擅长指出这些(以及其他一些常见错误)。


推荐阅读