我正在编写一个非常简单的 shell,它删除给定文件夹中的文件,在本例中是该文件夹中的所有 .csv 文件。
代码如下所示:
#!/bin/bash
# Used to clean folder
MinVal=0
Files=$(ls -1 *.csv | wc -l)
if [ $Files -gt $MinVal ];then
rm *.csv
echo -e "\e[31;43m***** DONE *****\e[0m"
else
echo -e "\e[31;43mThere is no valid file to delete, please check\e[0m"
fi
shell 脚本按预期工作,但是当您执行 shell 并且文件夹中没有 .csv 文件时,终端会显示以下内容:
ls: cannot access *.csv: No such file or directory
当然它也显示else
消息:
There is no valid file to delete, please check
有没有办法避免ls: cannot access *.csv: No such file or directory
并直接进行else
错误处理?
问候。
答案1
发生这种情况是因为shell*.csv
逐字传递,这是默认的 POSIX 行为。ls
如果你想避免这种情况,你应该使用nullglob
不返回任何内容的 glob,而不是返回输入的逐字字符串。但这有一个问题,因为ls
在没有提供文件时会有不同的行为。
请尝试这样做,这样做的好处是可以避免在文件名中嵌入换行符的情况下出现错误:
shopt -s nullglob
filenames=( *.csv ) # put all files in an array
files="${#filenames[@]}" # get number of files
答案2
如果您只想抑制警告消息,那么ls
最直接的做法就是重定向stderr
到/dev/null
,例如:
Files=$(2>/dev/null ls -1 *.csv | wc -l)
请注意,重定向stderr
将抑制全部*.csv
此命令导致的错误,包括可能与目录中缺少文件无关的错误。
计算文件数的更好解决方案可能是使用find
而不是ls
,例如:
find . -maxdepth 1 -name "*.csv" | wc -l
事实上,您可能还想使用来find
执行删除:
find . -maxdepth 1 -name "*.csv" -delete
我还注意到您使用了-r
标志rm
,这看起来可能是无意的,因为您正在使用 执行平面搜索,ls
然后使用 进行递归删除rm
。
但坦率地说,我不确定为此任务编写脚本是否有意义。与直接运行命令相比,该脚本有什么好处?换句话说,这有什么问题:
# Check for files
ls *.csv
# Delete the files
rm *.csv
为什么运行脚本比运行这些命令更好?看起来您只是增加了开销并将一条错误消息替换为另一条错误消息。