Bash脚本应该具有多大的防御能力?

Bash脚本应该具有多大的防御能力?,bash,Bash,我最近偶然发现了一个非常基本的代码片段,并开始怀疑Bash脚本需要多大的防御能力 [[-f$file]]&&rm--“$file”| | echo”文件不存在。 当您也可以将文件传递到rm并让rm自己进行检查时,检查文件是否存在的目的是什么?如果原因是您可以自己控制显示为错误消息的内容,那么为什么不需要同时检查文件是否可写才能将其删除?这让我相信,如果你在调用命令之前开始测试可能的条件——为了保持一致——你需要检查每一个可能发生的情况,否则你最终会得到自己和外部命令的错误消息(rm) 我想知道的

我最近偶然发现了一个非常基本的代码片段,并开始怀疑Bash脚本需要多大的防御能力

[[-f$file]]&&rm--“$file”| | echo”文件不存在。

当您也可以将文件传递到
rm
并让
rm
自己进行检查时,检查文件是否存在的目的是什么?如果原因是您可以自己控制显示为错误消息的内容,那么为什么不需要同时检查文件是否可写才能将其删除?这让我相信,如果你在调用命令之前开始测试可能的条件——为了保持一致——你需要检查每一个可能发生的情况,否则你最终会得到自己和外部命令的错误消息(
rm

我想知道的另一个稍微复杂一点的例子是

ffmpeg-n-i“/$file”-编解码器:flac“/${file%.*}.flac”

这将获取一个文件并使用FLAC编解码器对其进行转码。首先检查输入文件是否存在、该文件是否可读以及输出文件的位置是否可写是否明智?(通过向
ffmpeg
提供选项
-n
,检查输出文件是否已经存在,这意味着不覆盖现有文件。)


如果我不添加这些检查,所有这些都将由
ffmpeg
本身进行检查。

脚本的防御程度取决于您希望对脚本执行的控制的粒度

如果您对命令处理失败的方式感到满意,并且脚本的其余部分可以毫无问题地执行,无论它是失败还是成功,您可以完全盲目地执行它,忽略它的输出和返回值

command_to_be_ignored >/dev/null 2>&1 ||:
也许你仅仅知道它是成功还是失败就满足了

command_to_be_ignored >/dev/null 2>&1 || result=$?
如果您运行一个任务关键型脚本,并且希望对许多潜在的故障模式做出反应,那么您将需要捕获并测试命令的输出,或者测试前提条件,如果不满足这些条件,则执行不同的操作

顺便说一句,检查命令执行的先决条件并不会使错误处理变得不必要,因为命令可能仍然会因为并行发生的事情而失败,或者只是因为您没有完全理解(或能够测试)所有潜在的故障模式。检查前置条件用于更改程序在特定情况下的操作,而不是避免处理错误


总之,这是一个工程问题:了解底层机制,知道需要做什么,并做出适当的权衡。

删除文件不需要对文件的写入权限,您需要对包含itHow防御的目录拥有写权限,这可能是一个没有真正答案的意见问题。这将取决于您的环境和失败的成本。如果脚本失败或做了错误的事情不会造成任何伤害,那么它可能不需要太过保守。如果它可能会意外地重新格式化错误的分区,那么,您可能需要进行大量的错误检查。控制错误消息是一个错误,而不是一项功能。如果只是将其编码为
rm“$file”
,您可能会收到一条错误消息(在stderr上)这说明了一些有用的信息,例如:
/path/to/file:permission denied
,而不是stdout上的错误消息。@EricRenouf一旦发生意外错误,不允许程序继续执行的好处之一是保护自己免受意外后果的影响(由于不完全的知识,异常情况的复杂性等)。在我自己的脚本中,我有一种错误处理方法,它只需很少的额外努力就可以为我提供这一好处(构建这个东西并不是一件小事)。我倾向于有点教条,从不默认忽略脚本中的失败,因为它对我来说是多么简单。
-f
不仅仅是检查名称是否存在,而是检查它是否是一个常规文件。
$file
给出的名称可能是一个目录、fifo、unix套接字或设备,在这种情况下,
-f
将失败。实际上,
echo
消息(应该重定向到stderr)并不完全正确,
-f
失败意味着该名称不是一个常规文件,而不是它不存在。