Этот ответ показывает, что можно скопировать все файлы, включая скрытые, из каталога src
в каталог dest
следующим образом:
mkdir dest
cp -r src/. dest
В ответе или его комментариях нет объяснения, почему это действительно работает, и, похоже, никто не находит документацию по этому вопросу.
Я опробовал несколько вещей. Во-первых, нормальный случай:
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src dest
$ ls -A dest
dest_file src
Затем с /.
в конце:
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/. dest
$ ls -A dest
dest_file .dotfile src_dir src_file
Таким образом, это ведет себя аналогично *
, но также копирует скрытые файлы.
$ mkdir src src/src_dir dest && touch src/src_file src/.dotfile dest/dest_file
$ cp -r src/* dest
$ ls -A dest
dest_file src_dir src_file
.
и ..
являются правильными жесткими ссылками, как объяснено здесь , так же, как и сама запись каталога.
Откуда происходит это поведение и где оно задокументировано?
cp
Ссылка ясно объясняет , какcp -R
работает..
и..
каталоги, как и любые другие каталоги, в них нет ничего волшебного или таинственного..
и..
не ведите себя как другие каталоги.Ответы:
Поведение является логическим результатом документированного алгоритма для
cp -R
. Смотрите POSIX , шаг 2f:.
и..
каталоги, соответственно текущий каталог и родительский каталог. Ни то, ни другое не является особенным с точки зрения оболочки, поэтому ни то, ни другое не касается расширения, и каталог будет скопирован, включая скрытые файлы.*
с другой стороны, будет расширен список файлов, и именно здесь скрытые файлы отфильтрованы.src/.
текущий каталог внутриsrc
, которыйsrc
сам по себе;src/src_dir/..
Этоsrc_dir
родительский каталог, который сноваsrc
. Поэтому извнеsrc
, еслиsrc
это каталог, указывающийsrc/.
илиsrc/src_dir/..
в качестве исходного файлаcp
эквивалентный, и скопировать содержимоеsrc
, включая скрытые файлы.Смысл определения в
src/.
том, что он потерпит неудачу, еслиsrc
не является каталогом (или символической ссылкой на каталог), тогда какsrc
не будет. Он также будет копировать только содержимоеsrc
, не копируяsrc
себя; это также соответствует документации:Таким образом
cp -R src/. dest
копирует содержимоеsrc
вdest/.
(исходный файл находится.
вsrc
), тогда какcp -R src dest
копирует содержимоеsrc
вdest/src
(исходный файлsrc
).Еще один способ думать об этом - сравнивать копирование
src/src_dir
иsrc/.
, а не сравниватьsrc/.
иsrc
..
ведет себя так же, какsrc_dir
в первом случае.источник
src
, скопирует каталог вdest
,src/.
скопирует содержимое. Я постараюсь прояснить этот вопрос.src/.
иsrc/*
(заметьте, нетsrc/.*
);src/*
не включает скрытые файлы, если их игнорируетsrc
содержит,src/.
но это означает, что содержащий каталог каталога зависит от того, как вы называете каталог. Конечно, наличие.
ссылок в некотором смысле означает, что все каталоги содержат самих себя, но это может быть не интуитивно понятно для всех. Вместо этого поведения можно было бы также предположить, что «каталог, содержащий каталогfoo
» будет определятьсяfoo/..
, и в этом случае не будет иметь значения, будем ли мы ссылаться наfoo
илиfoo/.
: результирующий содержащий каталог будет таким же.foo
иfoo/.
кажется немного деликатным, но я не против, я также нахожу это немного забавным.Когда вы бежите
cp -R src/foo dest
, вы получитеdest/foo
. Таким образом, если каталогdest/foo
не существует,cp
создайте его, а затем скопируйте содержимоеsrc/foo
вdest/foo
.Когда вы запускаете
cp -R src/. dest
, видите ,cp
чтоdest/.
существует, и тогда это просто вопрос копирования содержимогоsrc/.
вdest/.
.Когда вы думаете о нем , как копирование каталога с именем
.
изsrc
и объединения его содержимое существующего каталогаdest/.
, это будет иметь смысл.источник