ls -R /home/username/some/path
是相同的
ls - R /home///username/////////////some////path
/
对bash 中' ' 字符的这种解释有什么解释吗?
我看不到 ls 程序的实现,但我可以看到我的实现:
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <assert.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
/* This program recursively prints files from given path. Should
be equivalent to ls -R /given/path call from shell, except we
don't concatenate '@' character at the end of symbolic link name,
'/' if directory entry is directory, we don't sort output etc.. */
static void error_fatal (char *message);
static void traverse (char *filename);
int
main (int argc, char **argv)
{
assert (argc == 2);
traverse (argv[1]);
exit (EXIT_SUCCESS);
}
static void
traverse (char *filename)
{
struct stat stats;
DIR *dir;
struct dirent *entry;
if (lstat (filename, &stats) < 0)
error_fatal ("lstat");
if (S_ISDIR (stats.st_mode))
{
printf ("\n%s:\n", filename);
if ((dir = opendir (filename)) == NULL)
error_fatal ("opendir");
if (chdir (filename) < 0)
error_fatal ("chdir");
// In the first pass, we print all directory entries.
while ((entry = readdir (dir)) != NULL)
{
if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name,
".."))
continue;
printf ("%s\t", entry->d_name);
}
putchar ('\n');
rewinddir (dir);
// In the second pass, we examine if entry is directory, and if so, recursively call traverse() function.
while ((entry = readdir (dir)) != NULL)
{
if (!strcmp (entry->d_name, ".") || !strcmp (entry->d_name, ".."))
continue;
if (lstat (entry->d_name, &stats) < 0)
error_fatal ("lstat");
if (S_ISDIR (stats.st_mode))
{
char *a;
int size =
sizeof (char) * (2 + strlen (filename) +
strlen (entry->d_name));
a = (char *) malloc (size);
if (a == NULL)
error_fatal ("malloc");
if (getcwd (a, size) == NULL)
error_fatal ("getcwd");
strcat (a, "/");
strcat (a, entry->d_name);
traverse (a);
free (a);
}
}
if (chdir ("..") < 0)
error_fatal ("chdir");
closedir (dir);
}
}
static void
error_fatal (char *message)
{
perror (message);
exit (EXIT_FAILURE);
}
uname -a
给我:
Linux mk-Inspiron-5570 4.15.0-43-generic #46-Ubuntu SMP Thu Dec 6 14:45:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux
bash --version
给我:
GNU bash, version 4.4.19(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
答案1
原因很简单:因为它是一个不bash
具体的标准,而是由POSIX 标准, 看定义章节,第 3.266 节 路径名
多个连续的斜线被视为与一个斜线相同。
这些规范旨在实现可移植性,并指定类 Unix 操作系统和实用程序的行为方式。bash
如果要将其用作/bin/sh
shell,则必须支持它,在 Ubuntu 上,它实际上曾经被符号链接到/bin/sh
。另请参阅sh 链接到 dash 有什么意义?
答案2
来自开放群组基础规范第 7 期,2018 年版-> 定义 ->3.271 路径名:
用于标识文件的字符串。在 POSIX.1-2017 的上下文中,路径名可能限制为 {PATH_MAX} 个字节,包括终止空字节。它具有可选的开头 <slash> 字符,后跟零个或多个由 <slash> 字符分隔的文件名。路径名可以可选地包含一个或多个尾随 <slash> 字符。多个连续的 <slash> 字符被视为与一个 <slash> 相同,除非恰好有两个前导 <slash> 字符的情况。
注意:如果路径名仅由与可移植文件名字符集(请参阅可移植文件名字符集)中的字符对应的字节、<slash> 字符和一个终止 <NUL> 字符组成,则该路径名在所有受支持的语言环境中均可用作字符串;否则,路径名可能只是一个字符串(而不是字符串)。此外,由于 <slash> 字符的单字节编码必须在所有语言环境中相同,并且不能出现在多字节字符中,因此即使路径名不是字符串,对路径名中 <slash> 字符的引用也是明确定义的。但是,此属性不一定适用于可移植文件名字符集中的其余字符。
路径名解析在路径名解析中有详细定义。