- при указании
ls --directory a*
следует указывать только каталоги, начинающиеся сa*
- НО это перечисляет файлы И каталоги, начинающиеся с
a
Вопросы :
- где я могу найти какую-то документацию по этому вопросу, кроме как
man
иinfo
где, я думаю, я внимательно посмотрел? - это работает только в BASH?
echo a*
также покажет вам файлы, начинающиеся сa
(если есть). Просто чтобы прояснить, что это неls
делает это, но удар.Ответы:
a*
И*a*
синтаксис реализуется командным, а не поls
команде.Когда вы печатаете
По приглашению вашей оболочки оболочка расширяется
a*
до списка всех существующих файлов в текущем каталоге, имена которых начинаются сa
. Например, он может расширятьсяa*
до последовательностиa1 a2 a3
и передавать их в качестве аргументовls
. Самаls
команда никогда не видит*
персонажа; он видит только три аргументаa1
,a2
иa3
.В целях расширения подстановочного знака «файлы» относятся ко всем объектам в текущем каталоге. Например, это
a1
может быть обычный файл,a2
каталогa3
или символическая ссылка. Все они имеют записи каталога, и расширению подстановочного знака оболочки не важно, к какому объекту относятся эти записи.Практически во всех оболочках, через которые вы можете встретиться (bash, sh, ksh, zsh, csh, tcsh, ...), используются символы подстановки. Детали могут различаться, но основной синтаксис
*
соответствия нуля или более символов и?
соответствия любому отдельному символу является достаточно последовательным.В частности, для bash это описано в разделе «Расширение имени файла» руководства по bash; запустите «
info bash
Поиск по расширению имени» или посмотрите здесь .Тот факт, что это делается оболочкой, а не отдельными командами, имеет некоторые интересные (а иногда и удивительные) последствия. Лучшее в этом то, что подстановочные знаки согласованы (почти) для всех команд; если оболочка этого не сделает, некоторые команды неизбежно не будут беспокоиться, а другие сделают это немного иначе, чем, по мнению автора, «лучше». (Я думаю, что у командной оболочки Windows есть эта проблема, но я недостаточно знаком с ней, чтобы комментировать дальше.)
С другой стороны, сложно написать команду для переименования нескольких файлов. Если вы напишите:
он, вероятно, потерпит неудачу, поскольку
*.log.bak
расширяется на основе файлов, которые уже существуют в текущем каталоге. Есть команды, которые делают такие вещи, но они должны использовать свой собственный синтаксис, чтобы указать, как файлы должны быть переименованы. Некоторые команды (такие какfind
) могут делать свое собственное расширение подстановочного знака; Вы должны процитировать аргументы для подавления расширения оболочки:Расширение подстановочного знака оболочки полностью основано на синтаксисе аргумента командной строки и набора существующих файлов. Это не может быть затронуто значением команды. Например, если вы хотите переместить все
.log
файлы в родительский каталог, введите:Если вы забыли
..
:и
.log
в текущем каталоге окажется ровно два файла, он расширится до:который переименует
one.log
и ударитtwo.log
.РЕДАКТИРОВАТЬ : И после 52 голосов, принять и значок Гуру, может быть, я действительно должен ответить на вопрос в названии.
-d
Или--directory
вариантls
не сказать это только список каталогов. Это говорит ему перечислять каталоги так же, как и они сами, а не их содержимое. Если вы задаете имя каталога в качестве аргументаls
, по умолчанию он будет перечислять содержимое каталога, поскольку это обычно то, что вас интересует.-d
Опция указывает ему перечислить только сам каталог. Это может быть особенно полезно в сочетании с подстановочными знаками. Если вы введете:ls
предоставит вам длинный список каждого файла , имя которого начинается сa
, и содержимого каждого каталога, имя которого начинается сa
. Если вы просто хотите получить список файлов и каталогов, по одной строке для каждого, вы можете использовать:что эквивалентно:
Помните еще раз, что
ls
команда никогда не видит*
персонажа.Что касается того, где это задокументировано,
man ls
покажет вам документацию дляls
команды практически на любой Unix-подобной системе. В большинстве систем на основе Linuxls
команда является частью пакета GNU coreutils; если у вас естьinfo
команда, либоinfo ls
илиinfo coreutils ls
должны дать вам более точную и полную документацию. Другие системы, такие как MacOS, могут использовать другие версииls
команды и могут не иметьinfo
команды; для этих систем используйтеman ls
. Иls --help
покажет относительно короткое сообщение об использовании (117 строк в моей системе), если вы используете реализацию GNU coreutils.И да, даже специалистам нужно время от времени обращаться к документации. Смотрите также эту классическую шутку .
источник
a*
расширяется до списка всех файлов в текущем каталоге , имена которых начинаются сa
.ls subdir/a*
echo
это. Поэтому, если вы хотите знать, что происходит, когда вы это делаетеls a*
, сначала выполнитеecho ls a*
echo a*
... оболочка все равно расширяетсяshopt -s failglob
вызывает то же поведение. Установка,nullglob
но неfailglob
приводит, например,*nosuchfile*
к расширению до пустой строки.Смотрите ответ Кита Томпсона; но объяснить, почему
ls --directory a*
отображаются файлы и каталоги:--directory
опция не подавляет файлы, не относящиеся к каталогам. Вместо этого он перечисляет каталоги как таковые, в то время как в противном случае он перечисляет их содержимое. Пример:источник
-F
опциейЧтобы быть очень явным, это задокументировано на странице руководства ls (1) :
-d, --directory перечисляет записи каталога вместо содержимого и не разыменовывает символические ссылки
чтобы быть справедливым, «записи вместо содержания», вероятно, может быть более объяснительным:
источник
подстановка
Как уже было объяснено, расширение
*
(и подобные расширения) называетсяglob
bing в жаргоне Unix и обычно является функцией командного процессора (в переводе Unix на языке Unix это называется «оболочка»). Таким образом, глобализация может быть использована и во многих других местах; введитеman 7 glob
в оболочке классического дистрибутива Linux (или посмотрите это ), чтобы узнать больше оglob
bing.В ранних версиях Unix
glob
фактически была реализована отдельная программа, которая называлась/etc/glob
(см. Стр. 10 этого старого руководства UNIX для документации по этому вопросу). В настоящее время это подпрограмма кода, предоставляемая библиотеками кода, и она обычно используется оболочками. Источник : Википедия .Справочники
Что касается того, почему
ls -d
списки файлов, а также каталоги ...Страница
ls
man объясняет, почему это происходит, но с очень кратким объяснением. Итак, вот попытка расширенного объяснения:По умолчанию
ls
перечисляет содержимое каталогов, когда им даны их имена, и будет делать то же самое для символических ссылок на каталоги. В-d
опции означает, «когда дано имя (ы) каталог (страна)» (которые также могут быть заданы неявно с помощьюglob
Бинга) , показывает только _name_s каталога (страна), но не их содержание. Точно так же, когда предоставляется (явно или неявно ) имя (я) символических ссылок на каталоги , показывается имя файла символической ссылки, а не содержимое каталога, на который она ссылается.-d
Насколько я могу судить, эта опция не имеет никакого отношения к тому, какие элементы перечислены; это можно сделать (источник: здесь ) сfind
, например , так:find . -maxdepth 1 -type d
. Я не уверен, есть ли хороший способ сделать это только с помощью GNUls
. Вот несколько примеров использованияfind
команды.Итак, подведем итог: по умолчанию
ls
показывает содержимое каталогов, когда дан их путь.-d
изменяет это поведение, показывая только имя каталога, как это будет сделано для стандартного файла.источник
Документация не говорит, что в ней перечислены только записи каталога, а когда она
ls
получает имя каталога, она перечисляет запись dir, а не ее содержимое. Лучший способ понять это на примере:источник
Документация является частью оболочки . В частности, оболочка выполняет различные расширения и замены в определенном порядке перед выполнением команды.
Последовательность слов расширений для оболочки , совместимой с Bourne является
Таким образом,
ls
команда даже не видит*
символы, аргументы уже расширены всеми файлами, соответствующимиa*
шаблону glob. Это непохоже на Windows, где каждая команда, нуждающаяся в перемещении имени файла, должна реализовать эту функцию сама.источник
Ключевое слово, которое вам нужно (
man bash
) - «Расширение пути».источник