Как распаковать каталог, а затем удалить оригиналы, включая каталог?

30

Я пытаюсь tarсобрать коллекцию файлов в каталоге my_directory и удалить оригиналы с помощью команды:

tar -cvf files.tar my_directory --remove-files

Однако это только удаление отдельных файлов внутри каталога, а не самого каталога (это то, что я указал в команде). Что мне здесь не хватает?

РЕДАКТИРОВАТЬ:

Да, я полагаю, опция 'remove-files' довольно буквальная. Хотя я тоже нашел справочную страницу по этому вопросу неясной. (В Linux я не очень сильно различаю каталоги и файлы, и иногда забываю, что это не одно и то же). Похоже, что консенсус в том, что он не удаляет каталоги.

Тем не менее, мой главный побудительный момент для постановки этого вопроса связан с обработкой tar абсолютных путей. Поскольку вы должны указать относительный путь к файлу / файлам, которые нужно сжать, вы должны перейти в родительский каталог, чтобы правильно его смонтировать. Насколько я понимаю, использование любой команды «rm» в этой ситуации потенциально опасно. Таким образом, я надеялся упростить ситуацию, заставив tar самостоятельно выполнить удаление.

Например, представьте сценарий резервного копирования, в котором каталог для резервного копирования (т. Е. Tar) включен в качестве переменной оболочки. Если это значение переменной оболочки было введено неверно, возможно, в результате удастся удалить файлы из любого каталога, в котором вы оказались в прошлом.

Николас
источник
Николас, твоя точка зрения, что это добавляет опасность необходимости удалять дерево каталогов на дополнительном шаге, абсолютно верна. Я думаю, что должно быть возможно сделать это безопасно архиватором. Я также считаю, что это было намерение создателей GNU tar, по крайней мере, так должно было быть ;-)
мит
2
Я обнаружил, что опция --remove-files действительно удаляет содержащий каталог - по крайней мере, на некоторых платформах / в некоторых версиях - и в моем случае. Возможно, в вашем случае оставшийся каталог не был полностью пустым из-за того, что некоторые файлы были изменены после изменения.
isync
@isync Я, кажется, испытываю --remove-файлы, удаляя каталоги в Ubuntu 14.04. За исключением моего случая, я не хочу этого. Хаха
Брэдли Оделл

Ответы:

12

Вам не хватает части, которая говорит, что --remove-filesопция удаляет файлы после добавления их в архив.

Вы можете выполнить операцию архивирования и удаления файла с помощью команды вроде:

find / path / to / be / archive / -depth -type d -empty -exec rmdir {} \;


Обновление: Вас может заинтересовать чтение этого короткого обсуждения Debian,
ошибка 424692: --remove-files жалуется, что каталоги «изменились, когда мы читаем их» .

Nik
источник
Может быть, это на самом деле: -cменяет каталог до того, как tarначинает свою работу (и вроде не возвращается, пока не выполнит)? Я предполагаю, что он удалил бы подкаталоги, если бы они были включены в архив (но я не проверял это).
Арджан
@ Араджан, я не думаю, что это c'как-то связано с этим; 'remove-files'намеренно не удаляет каталоги.
Ник
Ага, я нахожу краткое объяснение «удалите файлы после добавления их в архив» со manстраниц не слишком ясно об этом, но я предполагаю, что вы правы. Тем не менее, я бы не ожидал, что упомянутый каталог -cбудет удален, даже если tar он также удалит каталоги. (Для меня это было бы похоже на удаление текущего каталога, а следовательно, и самого архива, когда он не используется -c...?) Но если -remove-filesвсегда оставлять каталоги на месте, то я, конечно, просто усложняю вещи здесь. ;-)
Арджан
3
--remove-filesошибка была исправлена ​​в tar-1.19.
x-yuri
19

Поскольку --remove-filesопция удаляет только файлы , вы можете попробовать

tar -cvf files.tar my_directory && rm -R my_directory

так что каталог удаляется только если tarвозвращается состояние выхода 0

pavium
источник
9
за исключением того, что вы должны проверить состояние выхода tar перед выполнением команды rm! иначе вы можете остаться без архива tar и файлов ...
Ким
1
При использовании каталогов одного уровня, я полагаю, что более безопасным вариантом будет использование «rmdir», а не «rm», поскольку это приведет к удалению только пустой директории. [См. Редактирование вопроса]
Николас
Но rmdirудаляет только пустые каталоги. Идея заключалась в том, чтобы удалить каталог и файлы в нем (при условии tar, успешно)
pavium
--remove-filesошибка была исправлена ​​в tar-1.19.
x-yuri
&& будет запускать следующую команду, только если предыдущая команда вышла из 0 (успех). Если он выходит> 0, следующая команда не будет выполнена. Вы также можете изменить это с помощью || - запускать только в случае сбоя первой команды. Хороший способ сделать ужасную проверку контента - перезапускает тот.
Киррус
6

Вы пытались поставить директиву --remove-files после имени архива? Меня устраивает.

tar -cvf files.tar --remove-files my_directory
Роберт Грубба
источник
1
Скорее всего, поведение tar изменилось с тех пор, как был задан этот вопрос. Для меня нет разницы в том, чтобы положить --remove-filesдо или после my_directory; в обоих случаях каталог удаляется.
Redburn
5
--remove-filesошибка была исправлена ​​в tar-1.19.
x-yuri
1
source={directory argument}

например

source={FULL ABSOLUTE PATH}/my_directory

 

parent={parent directory of argument}

например

parent={ABSOLUTE PATH of 'my_directory'/

 

logFile={path to a run log that captures status messages}

Тогда вы можете выполнить что-то вроде:

cd ${parent}

tar cvf Tar_File.`date%Y%M%D_%H%M%S` ${source}

if [ $? != 0 ]

then

 echo "Backup FAILED for ${source} at `date` >> ${logFile}

else

 echo "Backup SUCCESS for ${source} at `date` >> ${logFile}

 rm -rf ${source}

fi
shellking
источник
1

Вероятно, это была ошибка.

Также слово «файл» в этом случае неоднозначно. Но так как это параметр командной строки, я хотел бы, чтобы он означал также каталоги, потому что в unix / lnux все является файлом, а также каталогом. (Другое толкование, конечно, также справедливо, но нет смысла хранить каталоги в таком случае. Я бы посчитал это неожиданным и запутанным поведением.)

Но я обнаружил, что в некоторых дистрибутивах GNU Tar фактически удаляет дерево каталогов. Еще один признак того, что хранение дерева было ошибкой. Или, по крайней мере, какой-нибудь обходной путь, пока они не исправят это.

Вот что я опробовал на консоли Ubuntu 10.04:

mit: / var / tmp $ mkdir tree1                                                                                               
mit: / var / tmp $ mkdir tree1 / sub1                                                                                          
mit: / var / tmp $> tree1 / sub1 / file1                                                                                        

mit: / var / tmp $ ls -la                                                                                                    
drwxrwxrwt 4 root root 4096 2011-11-14 15:40.                                                                              
drwxr-xr-x 16 root root 4096 2011-02-25 03:15 ..
drwxr-xr-x 3 mit mit 4096 2011-11-14 15:40 tree1

mit: / var / tmp $ tar -czf tree1.tar.gz tree1 / --remove-files

# КАК ВЫ МОЖЕТЕ УВИДЕТЬ, ДЕРЕВО УЖЕ СЕЙЧАС:

mit: / var / tmp $ ls -la
drwxrwxrwt 3 root root 4096 2011-11-14 15:41.
drwxr-xr-x 16 root root 4096 2011-02-25 03:15 ..
-rw-r - r-- 1 мит 159 2011-11-14 15:41 tree1.tar.gz                                                                   


mit: / var / tmp $ tar --version                                                                                             
tar (GNU tar) 1.22                                                                                                           
Copyright © 2009 Free Software Foundation, Inc.

Если вы хотите увидеть его на своем компьютере, вставьте его в консоль на свой страх и риск:

смола - версия                                                                                             
CD / VAR / TMP
mkdir -p tree1 / sub1                                                                                          
> tree1 / sub1 / file1                                                                                        
tar -czf tree1.tar.gz tree1 / --remove-files
ls -la
мит
источник