我正在尝试让我的 shell 脚本更安全一些。如果由于某种原因未定义变量,我考虑使用默认值,例如:
rm -r "${OUTPUT_DIR:-/dev/null/this_path_does_not_exists}"
使用不存在的路径是我想出的解决方案。然后我想,如果有一个系统范围的接收器(/dev/null
),也许有一个文件或伪文件,可以安全地删除而不影响系统。所以我的问题如下 - 是否有一个文件:
- 可删除,不会造成任何损失、功能损失或数据丢失
- 自动“重新生成”(它可能不会被系统首先删除)
- 以超级用户身份删除不会删除它(我很惊讶可以删除 /dev/null :))
答案1
与其试图提出一个始终存在但也始终可以删除的文件(或目录),为什么不在使用变量之前显式检查变量呢?
[ -d "$OUTPUT_DIR" ] && rm -r -- "$OUTPUT_DIR"
如果$OUTPUT_DIR
为空或指向不存在或不是目录的内容,则不会尝试删除任何内容。
答案2
rm -f
或者rm -rf
不执行任何操作,并且如果未传递任何参数也不会抱怨,并且您通常希望-f
在脚本中使用以确保不会提示用户,因此您也可以执行以下操作:
rm -rf -- ${OUTPUT_DIR:+"$OUTPUT_DIR"}
我不能保证rm -rf -- "$OUTPUT_DIR"
也能像 IIRC 一样工作,有些系统将空字符串视为当前工作目录(如果rm
不像它拒绝那样拒绝这样做,这显然会很戏剧性rm -rf .
)。
[ -z "$OUTPUT_DIR" ] || rm -rf -- "$OUTPUT_DIR"
在我看来,它并不更长,也更清晰。
也可以看看:
rm -rf -- "${OUTPUT_DIR:?No output dir!}"
$OUTPUT_DIR
如果未设置或为空,则shell 会退出并出现错误。
答案3
/dev/null/something
保证不存在,因为/dev/null
保证存在并且不是目录。
或者您可以使用空字符串。这保证不是有效的文件名。但是,如果变量与其他内容连接,则空字符串是有风险的。
但如果您担心在未设置变量的情况下意外使用变量,请打开set -u
(适用于所有 sh 风格的 shell)。那么尝试使用未定义的变量是一个错误,而不是默默地使用空值。
(可以安排一个始终存在的文件,并且尝试删除似乎成功但将文件保留在适当的位置,使用自定义保险丝。但我不知道这有什么帮助:这里你需要一个rm
保证失败的文件,而不是一个保证成功的文件。)
关于安全性:除非您已将 安排为$OUTPUT_DIR
绝对路径,否则它可以以 开头-
,这看起来像是一个选项。因此,--
在将其传递给任何命令时,请确保在它之前传递。
rm -r -- "$OUTPUT_DIR"