Почему нет разницы между / и ////// в пути bash [дубликат]

На этот вопрос уже есть ответ здесь:

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
задан 24 December 2018 в 13:53

2 ответа

Причина проста: потому что это - стандарт, который не является bash конкретный, но указан стандартом POSIX, см. главу Определений, разделите 3.266 Пути

Несколько последовательных наклонных черт считаются тем же как одной наклонной чертой.

Эти спецификации предназначены для мобильности и указывают, как подобная Unix операционная система и утилиты должны вести себя. bash должен поддерживать его, если это хочет использоваться как /bin/sh оболочка, к которой на Ubuntu это на самом деле раньше было symlinked /bin/sh. См. также Какой смысл sh, связываемого с тире?

6
ответ дан 3 December 2019 в 06:22

От выпуск Выпуска 7, 2018 Спецификаций Основы Open Group-> Определения-> 3.271 Пути:

Строка, которая используется для идентификации файла. В контексте POSIX.1-2017 путь может быть ограничен байтами {PATH_MAX}, включая завершающийся пустой байт. Это имеет дополнительные символы <slash> начала, сопровождаемые нулем или большим количеством имен файлов, разделенных символами <slash>. Путь может дополнительно содержать один или несколько запаздывающих символов <slash>. Несколько последовательных символов <slash> считаются тем же как одним <наклонная черта>, за исключением случая точно двух ведущих символов <slash>.

Примечание: Если путь будет состоять только из соответствия байтов символам от переносимого набора символов для имен файлов (см. Переносимый набор символов для имен файлов), то символы <slash> и единственный символ <NUL> завершения, путь будет применим как символьная строка во всех поддерживаемых локалях; иначе путь мог бы только быть строкой (а не символьная строка). Кроме того, так как однобайтовое кодирование символа <slash> требуется, чтобы быть тем же через все локали и не произойти в многобайтовом символе, ссылки на символ <slash> в пути четко определены, даже когда путь не является символьной строкой. Однако это свойство не обязательно содержит для оставшихся символов в переносимом наборе символов для имен файлов.

Разрешение пути определяется подробно в Разрешении Пути.

2
ответ дан 3 December 2019 в 06:22

Другие вопросы по тегам:

Похожие вопросы: