为什么bash路径中的/和//////没有区别

mk1*_*024 1 command-line bash ls

ls -R /home/username/some/path
Run Code Online (Sandbox Code Playgroud)

是相同的

ls - R /home///username/////////////some////path
Run Code Online (Sandbox Code Playgroud)

/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);
}
Run Code Online (Sandbox Code Playgroud)

uname -a 给我:

ls -R /home/username/some/path
Run Code Online (Sandbox Code Playgroud)

bash --version 给我:

ls - R /home///username/////////////some////path
Run Code Online (Sandbox Code Playgroud)

Ser*_*nyy 6

原因很简单:因为它不是bash特定的标准,而是由POSIX 标准指定的,请参阅定义章节,第 3.266 节路径名

多个连续的斜线被认为与一个斜线相同。

这些规范旨在实现可移植性并指定类 Unix 操作系统和实用程序的行为方式。bash如果它想用作/bin/shshell就必须支持它,在 Ubuntu 上它实际上曾经被符号链接到/bin/sh. 另请参阅将 sh 链接到 dash 的意义何在?