为什么 Unix 允许带有句点的文件在最后名字的?这有什么用吗?
例如:
filename.
我这样问是因为我有一个简单的函数可以回显文件的扩展名。
ext() {
echo ${1##*.}
}
但是知道如果文件名以 a 结尾它不会打印任何内容.
,我想知道这样写是否会更可靠:
ext() {
extension=${1##*.}
if [ -z "$extension" ]; then
echo "$1"
else
echo "$extension"
fi
}
显然,这取决于您想要完成的任务,但如果.
不允许在文件名末尾添加 a,我一开始就不会想知道任何事情。
答案1
Unix 文件名只是字节序列,并且可以在任何位置包含除/
和 之外的任何字节。NUL
没有像 Windows 及其文件系统中那样的内置“扩展名”概念,因此没有理由不允许文件名以通常可以出现在其中的任何字符结尾(或开始) - a.
不再特殊比x
.
为什么 Unix 允许文件名称末尾带有句点? “字节序列”是一个简单且非排他性的名称定义,当没有动机理由去计算某些内容时,实际上并没有。制定并应用规则来具体排除某些内容需要更多工作。
它有什么用处吗?如果您想创建一个具有该名称的文件,当然可以。以 结尾的文件名有用途吗x
?我不能说我通常会创建一个以 a.
结尾的文件名,但是 和.
都是x
明确的一部分可移植文件名字符集这需要得到普遍支持,而且两者都没有任何特殊之处,所以如果我需要使用它(也许是机械生成的编码),那么我可以,并且我可以依赖它工作。
此外,引用当前目录和父目录的特殊文件名.
(点)和(点-点)是..
强制的通过 POSIX,并且都以.
.任何处理文件名的代码通常都需要解决这些问题。
答案2
真正的问题是,为什么任何操作系统都重视“.”。 ?这样做没有技术原因,它只是一个标准,可以帮助您在不检查的情况下假定文件类型。
如果您将 MP3 文件重命名为 .txt 并尝试在 Windows 中打开它,您将立即明白为什么该想法有缺点:您突然“无法”正确打开该文件。从技术上讲,如果不考虑速度等因素,“最佳”方法可能是在决定如何处理文件之前确定文件类型,因为扩展很容易被弄乱并可能导致问题。
linux 不关心名称中的句点的原因与非计算机人员不关心的原因相同:句点和任何其他字符之间没有固有的区别,除了某些程序碰巧被编码为看到的事实之外那个时期并特别对待它。
假设您实际上只想要扩展(这不是您的两个代码片段所做的),您可以使用以下内容:
ext(){
extension=
[[ $1 =~ \. ]] && extension="${1##*.}"
echo "$1 -> ${extension:-No extension}"
}
ext something. # something. -> No extension
ext something.txt # something.txt -> txt
ext something # something -> No extension
ext som.thing.mp3 # som.thing.mp3 -> mp3
ext .whatever # .whatever -> whatever
*注意最后一个。
如果您确实想在没有扩展名时返回文件名本身(就像您的代码一样),则没有理由使用您拥有的长 SH 样式的第二个片段。你写过:
ext() {
extension=${1##*.}
if [ -z "$extension" ]; then
echo "$1"
else
echo "$extension"
fi
}
这实际上只是:
ext(){
extension="${1##*.}"
# This line is what your first snippet is doing:
# echo "$extension"
# This line is what your second snippet is doing:
[[ $extension ]] && echo "$extension" || echo "$1"
}
这实际上只是:
# First snippet
ext(){
echo "${1##*.}"
}
# Second snippet
ext(){
extension="${1##*.}"
echo "${extension:-$1}"
}
您不能想当然地认为用户基本上可以输入任何内容。如果您想查看它实际上是什么类型的文件,请尝试使用 file 命令。因为解析文件名来尝试找出文件类型并不是剥皮的唯一方法。你甚至可以在 Linux 中使用一个简单的文件名:\