Почему 'cp -r../ *.' работать, но не 'cp -r...'

Кажется, я попал в самую точку. Я поискал в "обычных прибежищах" и ничего не нашел, а потом подумал: "Эй, а где бы в старые добрые времена *NIX-фрики писали об этом?

Юнет. Они размещали сообщения в Usenet. 30 апреля 2002 г. Кейси Шауфлер написал:

I was the final technical editor of the document, and had the unpleasant task of requesting its withdrawl after the completion of Draft 17.

In the end, only SGI and IBM cared enough about it to continue working on it, IBM would not pay for travel, and twice in Poughkeepsie was all I could handle.

More to the point, standards development fell off of the list of important things for computer companies right about 1995, and the security effort fell victem to that.

There where a number of issues with the Draft itself that didn't help. It should have been five seperate efforts (ACLs, Audit, Capabilities, Information Labels, MAC) rather that a single integrated document. The source for the draft disappeared for a year and was only partially recovered. Some sections where too ambitious for their intended purpose. Too much was designed by the working group.

2
26.06.2020, 22:41
1 ответ

Взгляните на команды, как они на самом деле выполняются:

$ set -x; cp -r../*.
+ cp -r../child../dir1../dir2../dir3../file1../file2../file3.
cp: cannot copy a directory, '../child', into itself, './child'
$ set -x; cp -r...
+ cp -r...
cp: cannot copy a directory, '..', into itself, '.'

Обе ваши команды пытаются скопировать каталог в себя, что приводит к зацикливанию. Реализация cpможет обнаружить это и остановиться в какой-то момент или продолжить копирование бесконечно (, например, GNU и BusyBox cpостанавливаются; FreeBSD cpпродолжает копирование до тех пор, пока не будет достигнут предел длины имени файла; аналогично, cpв MacOS продолжает копировать, поскольку этот другой вопрос на U&L , кажется, предполагает ).
В любом случае рекурсивное копирование каталога в себя в конечном итоге остановится с ошибкой.

Предполагая, что вопрос касается GNU cp(, который у вас, вероятно, есть в системе GNU/Linux ), в общем случае ваша вторая команда(cp -r...)скопирует(непредсказуемое? )часть дерева с корнем в .., обнаружить цикл и остановить с ошибкой без какой-либо дальнейшей обработки чего-либо в этом дереве.

С другой стороны, в вашей первой команде (cp -r../*.), cpдается восемь отдельных аргументов. Хотя копирование содержимого childв childзавершается ошибкой, другие каталоги и файлы копируются без проблем, поскольку ни один из них не содержит сам child.
Обратите внимание, однако, что это не будет «работать» должным образом на системах, в которых cpне обнаруживает циклы и продолжает рекурсивное копирование.


В качестве более безопасного подхода, чтобы скопировать все содержимое родительского каталога в текущий каталог (child), за исключением самого текущего каталога, вы можете использовать:

$ shopt -s nullglob dotglob extglob
$ cp -r../!(child).
5
18.03.2021, 23:23

Теги

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