Я понимаю, что это полезно. Но я немного запутался, потому что кажется, что эта функция нарушает стандарты.
поведение cp при рекурсивном копировании из a/.
b
идеально соответствует его "нормальному" поведению.
По умолчанию cp не создает родительские каталоги. Это можно изменить с помощью переключателя родителей :
--parents
use full source file name under DIRECTORY
Но что это значит?
Это означает, что пока команда
cp --parents -r some/path/to/source dest
скопирует содержимое исходного каталога в dest/some/path/to/source
, команда
cp -r some/path/to/source dest
скопирует содержимое исходного каталога в dest/source
.
Аналогично, команда
cp -r some/path/to/source/. dest
скопирует содержимое исходного каталога в dest/.
, который просто dest
.
Я подумал и a
это тот же путь.
a
и a/.
это тот же путь. Но в качестве аргумента для cp это просто строка.
Обратите внимание, что команды
cp --parents -r some/path/to/source dest
а также
cd some/path/to && cp --parents -r source dest
будет вести себя по-другому.
Как насчет cp -r a/inner/.. b
? Принимая во внимание ваше объяснение, не следует ли копировать файлы в b/..
(т.е. в текущий каталог)?
Ну да. Это исключение.
По крайней мере, в GNU-версии cp есть специальный случай для ..
basename.
Из coreutils-8.22/src/cp.c
:
if (parents_option)
{
[removed]
}
else
{
char *arg_base;
/* Append the last component of 'arg' to 'target_directory'. */
ASSIGN_BASENAME_STRDUPA (arg_base, arg);
/* For 'cp -R source/.. dest', don't copy into 'dest/..'. */
dst_name = (STREQ (arg_base, "..")
? xstrdup (target_directory)
: file_name_concat (target_directory, arg_base,
NULL));
}
Мотивация, по-видимому, заключается в том, чтобы избегать копирования за пределы целевой папки, что, хотя и идеально согласуется с поведением cp в любом другом случае, немного нелогично и может иметь неприятные последствия.
В конце концов, я не думаю, что кто-то будет ожидать команду
cp -r .. ~
влиять на файлы за пределами его домашнего каталога ...