使用替换变量字符串作为模式的 cksum 文件

使用替换变量字符串作为模式的 cksum 文件

我可以eval在下面的示例中避免还是没有其他方法?变量上的文件列表是动态的,我想对所有文件进行 cksum 。该目录中还有许多其他文件,但应该忽略它们。

$ Z="file1 file4"
$ echo ${Z//\ /,}
file1,file4
$ echo {${Z//\ /,}}
{file1,file4}
$ cksum {file1,file4}
927007485 136284 file1
2748059092 136286 file4
$ cksum {${Z//\ /,}}
cksum: {file1,file4}: No such file or directory
$ eval cksum {${Z//\ /,}}
927007485 136284 file1
2748059092 136286 file4

答案1

使用数组代替字符串:

files=( file1 file2 "filename with spaces" file50 "*my* file" )

cksum "${files[@]}"

请注意,上面的每个双引号都很重要,特别是当您的文件名中包含空格或文件名通配字符时。

答案2

解释为什么cksum {${Z//\ /,}}没有按您的预期工作:

  1. 根据 bash替换/扩展的顺序,发生大括号扩展参数替换
  2. 然而,它被记录在案“为了避免与参数扩展发生冲突,字符串 '${' 不被视为符合大括号扩展条件。” -- 所以 bash 在这里不执行大括号扩展。
  3. 然后 shell 最终进行参数替换,命令扩展为cksum {file1,file4}
  4. shell 不会返回并重新执行扩展列表,因此我们不会再次进行大括号扩展:我们只剩下单个单词“{file1,file4}”
  5. 并且没有这样的文件。

当您引入eval混合时,您明确要求 shell 再次检查扩展列表。现在我们可以在命令上进行大括号扩展cksum {file1,file4},然后您可以获得这两个文件的校验和。

相关内容