bash - BASH - 当 $@ 包含不存在的文件时如何使用 $@ 查找?
问题描述
我有一个函数,它传递了几个文件名作为参数。某些文件名可能指的是不存在或已被删除的文件。因为 args 中也可能有目录,所以我想获取作为 args 传递的所有文件的递归列表,以及目录中包含的所有可能作为 args 包含的文件的列表。
function SomeFunction () {
# get list of files recursively
fList=$(find $@ -type f)
do something with $fList
.
.
.
}
[~]$SomeFunction existentFile nonexistentFile existentNonEmptyDir
find: `nonexistentFile': No such file or directory
fList=$(find $@ -type f)
如果不是因为它会很好用nonexistentFile
。即使文件丢失,有没有办法进行同样的调用?
解决方案
忽略来自的警告是完全合理的find
。但是,如果您想过滤参数列表以查找在调用之前实际存在的内容,则可以显式执行此操作:
SomeFunction() {
local -a existing_args=( )
for arg in "$@"; do
[[ -e "$arg" ]] && existing_args+=( "$arg" )
done
while IFS= read -r -d '' result; do
printf 'Processing result: %q\n' ## put your own code here
done < <(find "${existing_args[@]}" -type f -print0)
}
一些注意事项:
function
关键字取自 ; 的 ksh 函数声明语法function SomeFunction {
。函数名后面的括号取自 POSIX sh 函数声明语法SomeFunction() {
。将它们结合起来会得到既不兼容传统 ksh 也不兼容 POSIX sh 的结果。请参阅http://wiki.bash-hackers.org/scripting/obsolete- 引用
"$@"
确保正确处理带有空格、全局字符等的文件名;同样在数组扩展上,例如"${existing_args[@]}"
. existing_args
被定义为一个数组——一个字符串列表——而不是一个单独的字符串。这很重要,因为文件名本身就是字符串,并且尝试像列表一样迭代字符串通常是错误的(再次影响名称中包含空格、文字换行符、全局字符等的文件)。- 使用
find -print0
确保我们使用 NUL 分隔文件名。这很重要,因为 UNIX 中的文件名在内部作为 NUL 分隔的字符串传递;因此,NUL 是唯一保证不会出现在路径中的字符。IFS= read -r -d '' var
从这样一个 NUL 分隔的字符串中读取单个条目。 - Using
< <(...)
确保我们从...
' 的输出重定向到作为该重定向主题的循环,同时将find
- 而不是循环 - 放在子shell中。有关为什么这很重要的示例,请参阅BashFAQ #24。
推荐阅读
- pandas - 计算熊猫中连续值组的最大运行长度
- c++ - 将 unique_ptr 分配给原始指针
- tensorflow - tf.train.Saver 实例不关闭检查点文件
- go - golng 获取 url 和 resp.Body.Close()
- php - 在 PHP 中没有命令“include”的包含文件的任何路径
- php - 使用mysql数据库以php形式自动选择下拉菜单
- javascript - 使用 Jade/Pug 进行 Jquery 自动完成
- javascript - 我不明白为什么我的 JS 函数会导致错误
- c# - 比较图像源
- mongodb - 如何使用 Docker (Plesk) 为 MongoDB 启用访问控制