Существует фундаментальная разница между этими двумя формами аргументов. И важно понять, что происходит.
При ../foldersource/.этом аргумент передается без изменений в команду, будь то cpили rmили что-то еще. Это зависит от команды, имеет ли эта конечная точка особую или уникальную семантику, отличающуюся от стандартного соглашения Unix простого указания на каталог, в котором она находится; и то rmи другое, cpкажется, рассматривает это как особый случай.
С ../foldersource/*аргументом сначала раскрывается оболочкой, прежде чем команда когда-либо будет выполнена и передана какие-либо аргументы. Таким образом, rmникогда не видит ../foldersource/*; он видит расширенную версию ../foldersource/file1.ext ../foldersource/file2.ext ../foldersource/childfolder1и так далее. Это важно, потому что операционные системы ограничивают количество аргументов, передаваемых команде, обычно всего несколько сотен.
It's up to the command whether that trailing dot makes any senseХм, точка всегда ссылается на сам каталог, в котором она находится, поэтому она ../foldersource/.не должна отличаться от описания ./foldersource/и, фактически, это просто избыточный способ заявить одно и то же. Ни одна команда не пытается «разобраться» с точкой или двойной точкой, поскольку они являются стандартными в файловых системах Linux / Unix. rmпросто отклоняет удаление текущего рабочего каталога, как jimmijуказано в их ответе. Кроме того, обратите внимание, что вы используете ./во всех своих примерах, в то время как OP есть ../там. Отчасти (большая) разница.
Сергей Колодяжный
«cp -rfva ../foldersource/. ./» эквивалентен «cp -rfva ../foldersource ./», я хочу скопировать содержимое папки, но не корневой каталог
Несмотря на то, что в этом ответе сказано правильно, в нем отсутствует очень важное различие, как упомянуто в ответе @ roaima: вариант / * (обычно) не копирует файлы или каталоги, начинающиеся с.
Адам
@SergiyKolodyazhnyy Вы правы; .является стандартной конвенцией в Unix для обозначения тока непосредственно. Кроме того, спасибо за указание, что я использовал ./в своих примерах, когда я должен был использовать ../; Я исправлю это. Вы не правы относительно того, имеют ли команды смысл в конце; как точки OP вне (и я испытал с cp) , как rmи cpвести себя по- другому , когда замыкающая .присутствует. Я должен был написать что-то вроде: «Это зависит от команды, если конечная точка имеет особую или уникальную семантику». Я изменю свой ответ для ясности.
Эстрада
10
При копировании с использованием cp -a source/* target/вы копируете большинство файлов и каталогов из sourceв target. В частности, исключаемые элементы, вероятно, будут файлами, начинающимися с точки ( .) на верхнем уровне source.
Рассмотрим эти файлы (или каталоги) в source
apple # will be copied
banana/# will be copied, as will all its contents.cherry # will not be copied
При копировании с использованием cp -a source/. target/вы копируете все содержимое source, включая любые элементы, начинающиеся с точки ( .), вtarget
Рассмотрим эти файлы (или каталоги) в source
apple # will be copied
banana/# will be copied, as will all its contents.cherry # will be copied
Если вы используете bash, zshвы можете использовать эту dotglobопцию, чтобы изменить значение *так, чтобы она включала файлы и каталоги, начинающиеся с точки ( yashтакже есть dotglobопция; однако она затем включает .и ..в глобальные расширения, которые ограничивают ее удобство использования. См. Также FIGNORE='@(.|..)'в ksh93)
Интересно, cp -a source/. target/что гарантированно никогда не будет создан компонент target/source. (С другой стороны, cp -a source target/будет делать одно из двух в зависимости от того, существует он или нет target. См. Как рекурсивно копировать папку идемпотентным способом, используя cp для деталей.)
При удалении с помощью вы удаляете rm -rf source/*файлы и каталоги внутри, sourceкоторые не начинаются с точки ( .). С учетом dotglobнастроек, которые я уже упоминал. Он не удалит сам каталог source.
Когда вы попытаетесь удалить rm -rf source/.его, он потерпит неудачу - как уже объяснили другие - потому что POSIX запрещает удаление пути, последний компонент которого .или ... Ближайшим эквивалентом является rm -rf sourceудаление sourceкаталога и всего его содержимого независимо от того, начинаются они с точки или нет ..
Вы не можете этого сделать, rm -rf ../foldersource/.потому rmчто не допускаете этого, как явно указано в руководстве:
Любая попытка удалить файл с последним компонентом имени файла '.' или «..» отклоняется без каких-либо подсказок, как того требует POSIX.
и в руководстве по POSIX man 1p rmмы видим:
Если любой из файлов точка или точка-точка указана в качестве части базового имени операнда (то есть конечного компонента имени пути) или если операнд преобразуется в корневой каталог, rm должен записать диагностическое сообщение в стандартную ошибку и ничего не делать больше с такими операндами.
It's up to the command whether that trailing dot makes any sense
Хм, точка всегда ссылается на сам каталог, в котором она находится, поэтому она../foldersource/.
не должна отличаться от описания./foldersource/
и, фактически, это просто избыточный способ заявить одно и то же. Ни одна команда не пытается «разобраться» с точкой или двойной точкой, поскольку они являются стандартными в файловых системах Linux / Unix.rm
просто отклоняет удаление текущего рабочего каталога, какjimmij
указано в их ответе. Кроме того, обратите внимание, что вы используете./
во всех своих примерах, в то время как OP есть../
там. Отчасти (большая) разница.cp -rfva ../foldersource/. ./
НЕ эквивалентноcp -rfva ../foldersource ./
. Трейлинг/.
значительный.
является стандартной конвенцией в Unix для обозначения тока непосредственно. Кроме того, спасибо за указание, что я использовал./
в своих примерах, когда я должен был использовать../
; Я исправлю это. Вы не правы относительно того, имеют ли команды смысл в конце; как точки OP вне (и я испытал сcp
) , какrm
иcp
вести себя по- другому , когда замыкающая.
присутствует. Я должен был написать что-то вроде: «Это зависит от команды, если конечная точка имеет особую или уникальную семантику». Я изменю свой ответ для ясности.При копировании с использованием
cp -a source/* target/
вы копируете большинство файлов и каталогов изsource
вtarget
. В частности, исключаемые элементы, вероятно, будут файлами, начинающимися с точки (.
) на верхнем уровнеsource
.Рассмотрим эти файлы (или каталоги) в
source
При копировании с использованием
cp -a source/. target/
вы копируете все содержимоеsource
, включая любые элементы, начинающиеся с точки (.
), вtarget
Рассмотрим эти файлы (или каталоги) в
source
Если вы используете
bash
,zsh
вы можете использовать этуdotglob
опцию, чтобы изменить значение*
так, чтобы она включала файлы и каталоги, начинающиеся с точки (yash
также естьdotglob
опция; однако она затем включает.
и..
в глобальные расширения, которые ограничивают ее удобство использования. См. ТакжеFIGNORE='@(.|..)'
вksh93
)Интересно,
cp -a source/. target/
что гарантированно никогда не будет создан компонентtarget/source
. (С другой стороны,cp -a source target/
будет делать одно из двух в зависимости от того, существует он или нетtarget
. См. Как рекурсивно копировать папку идемпотентным способом, используя cp для деталей.)При удалении с помощью вы удаляете
rm -rf source/*
файлы и каталоги внутри,source
которые не начинаются с точки (.
). С учетомdotglob
настроек, которые я уже упоминал. Он не удалит сам каталогsource
.Когда вы попытаетесь удалить
rm -rf source/.
его, он потерпит неудачу - как уже объяснили другие - потому что POSIX запрещает удаление пути, последний компонент которого.
или..
. Ближайшим эквивалентом являетсяrm -rf source
удалениеsource
каталога и всего его содержимого независимо от того, начинаются они с точки или нет.
.источник
rm -rf .
неудаче .Вы не можете этого сделать,
rm -rf ../foldersource/.
потомуrm
что не допускаете этого, как явно указано в руководстве:и в руководстве по POSIX
man 1p rm
мы видим:источник