Я переместил все файлы из одного каталога, используя mv
, и случайно произвел опечатку в целевом пути расположения.
Система вернула сообщение, что каталог не существует, но мои файлы из исходного каталога были удалены.
Это ошибка? Следует ли перемещать файлы в несуществующее место, чтобы удалить перемещаемые файлы? (Это на Ubuntu 18.04.2 LTS.)
Особенности были:
test.txt
файл. /ben
с помощью sudo
. /ben
не существует. Команды и выходные данные были:
ben.b@c-w46:~/Desktop/test-folder$ sudo mv test.txt /ben
ben.b@c-w46:~/Desktop/test-folder$ cd /ben
bash: cd: /ben: Not a directory
В команде Вы на самом деле работали, Вы ничего не потеряли! Это успешно выполнилось при переименовании test.txt
кому: /ben
. Принятие test.txt
был регулярный файл, новое - также /ben
(они - тот же файл, в конце концов).
Причина Вы видите bash: cd: /ben: Not a directory
то, что это говорит относительно олова: /ben
не каталог. Можно все еще получить доступ к файлу.
Если Вы хотите избежать такой ошибки и силы mv
чтобы перестать работать, если место назначения не является каталогом, запишите запаздывание /
на нем или использование -t dir
. Например, любой из них предотвратил бы (очень незначительный!) проблема Вы испытали (с sudo
по мере необходимости):
mv test.txt /ben/ # no action, unless `/ben` is an existing directory
mv -t /ben test.txt # same deal, -t doesn't accept regular-file operands
mv -t /ben/ test.txt # you can even do both if you want
Информация об общей ситуации, описанной в Вашем вопросе - о проигрывающих файлах путем попытки переместить их - и что может и не может пойти не так, как надо, следует.
Как Rinzwind говорит, движущиеся файлы к несуществующему целевому каталогу не должны вызывать потерю данных при попытке его с помощью сингла mv
команда. Но это могло произойти, если бы Вы работали mv
несколько раз, такой как в цикле оболочки.
Например, предположите, что я имею:
ek@Apok:~/tmp$ ls -F
dest/ file02.txt file04.txt file06.txt file08.txt file10.txt
file01.txt file03.txt file05.txt file07.txt file09.txt
Перемещать все те файлы в dest
, Я должен передать все их имена к mv
, в команде как mv file*.txt dest/
или mv file*.txt dest
. В любом случае - то есть, пишу ли я целевое имя каталога с запаздывающей наклонной чертой - это делает правильную вещь. И в любом случае, если я пишу целевое имя каталога c орфографическими ошибками (говорят, путем записи dst
вместо этого), я получаю ошибку mv: target 'dst' is not a directory
и никакие данные не потеряны.
Однако предположите, что я должен был написать c орфографическими ошибками dst
, опустите запаздывание /
, и выполненный несколько mv
команды. Это было бы плохо, потому что когда место назначения mv
регулярный файл, mv
замены это!
ek@Apok:~/tmp$ mv file01.txt dst # bad if dst exists but isn't a directory
ek@Apok:~/tmp$ mv file02.txt dst # bad, I just lost the old file01.txt!
Поэтому многие люди предпочитают всегда писать целевые каталоги с запаздыванием /
в mv
:
ek@Apok:~/tmp$ mv file03.txt dst/
mv: failed to access 'dst/': Not a directory
Можно использовать mv -i
спросить Вас перед перезаписью, или mv -n
к тихо не перезаписывают. Иначе, mv
только спросите Вас прежде, чем перезаписать, если место назначения является файлом только для чтения. Одна причина рассмотреть это состоит в том, что это покрывает другие случаи, как mv file01.txt dest/
где Вы не поняли dest/file01.txt
существовавший и не хотел перезаписывать его.
Можно также использовать -t dest
вместо записи dest
в конце команды, например, mv -t dest file*.txt
. Это отказывается работать если dest
регулярный файл, независимо от того, пишете ли Вы запаздывание /
.
Используя автоматизированный механизм для выполнения нескольких таких команд может серьезно усугубить проблему. Например, как записано команда for f in file*.txt; do mv "$f" dest/; done
является напрасно сложным, но безопасным, потому что, если я случайно указал файл dst
вместо каталога dest
(но сохраненный наклонной чертой!), это дало бы мне один mv: failed to access 'dst/': Not a directory
ошибка на файл. Однако, если я опустил запаздывание /
, затем это переименовало бы каждый файл к dst
, замена предыдущего dst
, и только последний файл остался бы.
Подобные плохие результаты могут быть достигнуты с find
, включая в ситуациях, где может быть разумно использовать find
(но по-другому, и все еще с дополнительной осторожностью). Например, предположите, что я хотел переместить все файлы, соответствующие шарику file*.txt
во всем дереве каталогов (кроме dest
самостоятельно) в каталог dest
. Я мог бы сначала думать для использования этого:
find . -path ./dest -prune -o -name 'file*.txt' -exec mv {} dest/ \; # bad, don't use
Поскольку я включал запаздывание /
, запись dest/
вместо dest
, это не перезаписало бы названный файл dst
даже если я записал dst
вместо dest
. Но это имеет связанную проблему, что это перезапишет файлы, которые это уже скопировало, если файлы в различных частях дерева каталогов имеют то же имя. Например, если существует a/file01.txt
и a b/file01.txt
, каждый перезапишет другой. Чтобы избежать, чтобы также было лучше использовать что-то вроде этого:
find -path ./dest -prune -o -name 'file*.txt' -exec mv -it dest/ {} \; # okay
Другое преимущество -t dir
это, потому что это позволяет Вам указать целевой каталог перед перемещаемыми объектами, это совместимо с +
форма -exec
, куда несколько объектов передаются команде, таким образом, выполняя меньше команд (часто всего одна):
find -path ./dest -prune -o -name 'file*.txt' -exec mv -it dest/ {} + # good
В обоих случаях (они - то же за исключением \;
по сравнению с. +
) Я также передал -i
опция запросить перед каждой операцией, которая перезаписала бы файл. Если Вы просто хотите тихо пропустить их, записать n
вместо i
. Если Вы хотите протестировать Ваш find
команды сначала, можно записать echo
после -exec
но перед остальной частью команды для печати, что было бы выполнено. Например:
ek@Apok:~/tmp$ find -path ./dest -prune -o -name 'file*.txt' -exec echo mv -it dest/ {} +
mv -it dest/ ./file02.txt ./file06.txt ./file10.txt ./file09.txt ./file01.txt ./file04.txt ./file05.txt ./file07.txt ./file03.txt ./file08.txt
(Конечно, это находится в исходном каталоге, который я показал, где все файлы к перемещенному находятся в том же месте, и таким образом где find
излишество, и самая сложная разумная команда для использования mv -it dest/ file*.txt
.)
Нет, что Вы предлагаете, не должно быть возможным. Вероятно, необходимо лучше посмотреть на место назначения. Использовать history
получить список предыдущих данных команд.
Несколько вещей:
Если СУЩЕСТВУЕТ сделанное перемещение...
Посмотрите info coreutils 'mv invocation'
(интерактивная версия https://www.gnu.org/software/coreutils/manual/html_node/mv-invocation.html#mv-invocation) для того, как mv работает и более конкретный эта часть:
Это сначала использует часть того же кода, это используется ‘CP-a’ для копирования требуемых каталогов и файлов, затем (принимающий копию, за которой следуют), это удаляет оригиналы. Если копия перестала работать, то часть, которая была скопирована в целевой раздел, удалена. Если бы необходимо было скопировать три каталога от одного раздела до другого и копии первого каталога, за которым следуют, но второе не сделало, то первое оставили бы на целевом разделе и втором, и третье оставили бы на исходном разделе.
Таким образом, перемещение состоит из 2 частей:
cp -a
mv
Часть удаления перемещения сделана ПОСЛЕ ТОГО, КАК существует подтверждение, копия была сделана правильно.
если Ваш mv состоит из нескольких файлов, копия и перемещение сделаны промежуточные. Так a
mv a b c d e f /dir/
сделает a
cp a /dir/
rm a
...
cp f /dir/
rm f
таким образом, когда существует проблема промежуточный a и f, это закончит перемещение a и туда, где проблема появилась. Это также относится к использованию подстановочных знаков.
Относительно редактирования
sudo mv test.txt /ben
Это перемещает test.txt в / и переименовывает его к ben. И
ben.b@c-w46:~/Desktop/test-folder$ cd /ben
bash: cd: /ben: Not a directory
правильно ошибки. Сделайте a
ls -l /ben
и это покажет файл.
То, что всегда необходимо делать, добавляют / если Вы хотите переместить файл в каталог.
sudo mv test.txt /ben/
был бы ошибка как/ben/не делает существует.