Shellscript 错误处理

san*_*omo 2 linux shell bash centos shell-script

我正在编写一个非常简单的 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
Run Code Online (Sandbox Code Playgroud)

shell 脚本按预期工作,但是当您执行 shell 并且文件夹中没有 .csv 文件时,终端会显示以下内容:

ls: cannot access *.csv: No such file or directory
Run Code Online (Sandbox Code Playgroud)

当然,它还显示以下else消息:

There is no valid file to delete, please check
Run Code Online (Sandbox Code Playgroud)

有什么方法可以避免ls: cannot access *.csv: No such file or directory并直接进行else错误处理?

你好。

Chr*_*own 8

发生这种情况是因为shell*.csv逐字传递给ls它,这是默认的 POSIX 行为。如果您想避免这种情况,您应该使用nullglob以便不返回任何内容的 glob 不返回任何内容,而不是返回输入的逐字字符串。但这有一个问题,因为ls当没有提供文件时会有不同的行为。

试试这个,它的好处是避免在文件名中嵌入换行符的情况下出现错误:

shopt -s nullglob
filenames=( *.csv )  # put all files in an array
files="${#filenames[@]}"  # get number of files
Run Code Online (Sandbox Code Playgroud)


iga*_*gal 5

如果您只想抑制警告消息,ls那么最直接的做法就是重定向stderr/dev/null,例如:

Files=$(2>/dev/null ls -1 *.csv | wc -l)
Run Code Online (Sandbox Code Playgroud)

请注意,重定向stderr将抑制此命令导致的所有错误,包括可能与*.csv目录中缺少文件无关的错误。

计数文件的更好解决方案可能是使用find而不是ls,例如:

find . -maxdepth 1 -name "*.csv" | wc -l
Run Code Online (Sandbox Code Playgroud)

实际上,您可能还想使用它find来执行删除操作:

find . -maxdepth 1 -name "*.csv" -delete
Run Code Online (Sandbox Code Playgroud)

我还注意到您使用了-r标志rm,这看起来可能是无意的,因为您正在执行平面搜索,ls然后使用rm.

坦率地说,我不确定为此任务编写脚本是否有意义。这个脚本比直接运行命令有什么好处?换句话说,这有什么问题:

# Check for files
ls *.csv

# Delete the files
rm *.csv
Run Code Online (Sandbox Code Playgroud)

为什么运行脚本比运行这些命令更好?看起来您只是在增加开销并用另一个错误消息替换一个错误消息。