使用以句点结尾的文件名

使用以句点结尾的文件名

为什么 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 中使用一个简单的文件名:\

相关内容