#bash #shell #command-line #mv
#bash #оболочка #командная строка #mv
Вопрос:
Я пытаюсь получить directory
замену существующей folder
, но не могу сделать это с помощью mv — я верю, что есть способ, и я просто не знаю его (пока). Даже после просмотра справочной страницы и поиска в Интернете.
Если /path/to/
только содержит directory
, следующая команда переместится /path/to/directory
(исчезнет) в /path/to/folder
mv /path/to/directory /path/to/folder
По сути, это переименование, чего я и пытаюсь добиться.
Но если /path/to/folder
она уже существует, та же команда перемещает папку /path/to/directory
в /path/to/folder/directory
.
Я не хочу использовать cp
команду, чтобы избежать ввода-вывода.
Комментарии:
1. Может быть:
{ rm -rf /path/to/folder; mv /path/to/directory /path/to/folder; }
2. Я знаю, что мог бы сначала переместить цель вот так
mv folder moved amp;amp; mv directory folder amp;amp; rm -r moved
, но я думаю, что это ненужный взлом и оставил бы меня в ситуации, когда папка не существует — чего я хочу избежать.3. Ярлыка нет; существуют фундаментальные различия между каталогами и файлами, и вы не можете перезаписать одну папку другой подобным образом за один шаг. Однако важный вопрос заключается в том, почему это имеет значение, если
/path/to/folder
на данный момент не существует?4. Предполагая, что оба
folder
иdirectory
находятся в одной файловой системе, вы можете просто использоватьln
вместоcp
для минимизации ввода-выводаln /path/to/directory/* /path/to/folder amp;amp; rm -rf /path/to/directory
..5. Короче говоря,
ln <source> <target>
создайте новую запись каталога<target>
, которая ссылается на тот же базовый файл, что и<source>
. Ни одно из имен не является более «реальным», чем другое; оба ссылаются на файл с количеством ссылок, равным 2. Фактически,rm
на самом деле файл не удаляется; он просто удаляет ссылку на файл. Файловая система обрабатывает файлы для сбора мусора, на которые больше нет ссылок.
Ответ №1:
Вместо того, чтобы использовать cp
для фактического копирования данных в каждом файле, используйте ln
для создания «копий» указателей на файл.
ln /path/to/directory/* /path/to/folder amp;amp; rm -rf /path/to/directory
Обратите внимание, что это немного более атомарно, чем использование cp
; каждый отдельный файл появляется в /path/to/folder
за один шаг (т. Е. нет никаких шансов, что /path/to/folder/foo.txt
он когда-либо будет частично скопирован), но все еще есть небольшое окно, в котором некоторые, но не все файлы из /path/to/directory
были связаны с folder
. Кроме того, rm -rf
не является атомарным, но, предполагая, что это никого не интересует directory
, это не проблема. (Хотя, поскольку файлы из /path/to/directory
разорваны, вы можете увидеть изменения в количестве ссылок для файлов в разделе /path/to/foldoer
, которые меняются с 2 на 1. Маловероятно, что кого-то это будет волновать.)
То, что вы считаете файлом, на самом деле просто запись файловой системы в анонимный файл, управляемый файловой системой. Для примера рассмотрим простой пример.
$ mkdir d
$ cd d
$ echo hello > file.txt
$ cp file.txt file_copy.txt
$ ln file.txt file_link.txt
$ ls -li
total 24
12890456377 -rw-r--r-- 2 chepner staff 6 Mar 3 12:46 file.txt
12890456378 -rw-r--r-- 1 chepner staff 6 Mar 3 12:47 file_copy.txt
12890456377 -rw-r--r-- 2 chepner staff 6 Mar 3 12:46 file_link.txt
-i
Опция добавляет номер индекса каждой записи (первый столбец) к выходным данным; индекс можно рассматривать как уникальный идентификатор файла. В этом выводе вы можете видеть, что file_copy.txt
это совершенно новый файл с индексом, отличным от file.txt
. file_link.txt
имеет точно такой же индекс, что означает, что file.txt
и file_link.txt
— это просто два разных имени для одного и того же объекта. Число непосредственно перед владельцем — это количество ссылок; file.txt
и file_link.txt
оба ссылаются на файл с количеством ссылок, равным 2.
При использовании rm
вы просто удаляете ссылку на файл, а не сам файл. Файл не удаляется до тех пор, пока количество ссылок не уменьшится до 0. Для демонстрации мы удалим file.txt
и file_copy.txt
.
$ rm file.txt file_copy.txt
$ ls -li
total 8
12890456377 -rw-r--r-- 1 chepner staff 6 Mar 3 12:46 file_link.txt
Как вы можете видеть, единственная ссылка на file_copy
исчезла, поэтому индекс 12890456378 больше не отображается в выходных данных. (Действительно ли данные исчезли, зависит от реализации файловой системы.) file_link.txt
, однако, по-прежнему ссылается на тот же файл, что и раньше, но теперь с количеством ссылок 1, потому что file.txt
был удален.
Ссылки на файл не обязательно должны отображаться в одном каталоге; они могут отображаться в любом каталоге в одной и той же файловой системе, что является единственным предостережением при использовании этого трюка. ln
IIRC выдаст вам сообщение об ошибке, если вы попытаетесь создать ссылку на файл в другой файловой системе.