Linux tar no path

Команда tar в Linux

В качестве инструмента для архивации данных в Linux используются разные программы. Например архиватор Zip Linux, приобретший большую популярность из-за совместимости с ОС Windows. Но это не стандартная для системы программа. Поэтому хотелось бы осветить команду tar Linux — встроенный архиватор.

Изначально tar использовалась для архивации данных на ленточных устройствах. Но также она позволяет записывать вывод в файл, и этот способ стал широко применяться в Linux по своему назначению. Здесь будут рассмотрены самые распространенные варианты работы с этой утилитой.

Синтаксис команды tar

Синтаксис команд для создания и распаковки архива практически не отличается (в том числе с утилитами сжатия bzip2 или gzip). Так, чтобы создать новый архив, в терминале используется следующая конструкция:

tar опции архив.tar файлы_для_архивации

Для его распаковки:

tar опции архив.tar

Функции, которые может выполнять команда:

Функция Длинный
формат
Описание
-A —concatenate Присоединить существующий архив к другому
-c —create Создать новый архив
-d —diff
—delete
Проверить различие между архивами
Удалить из существующего архива файл
-r —append Присоединить файлы к концу архива
-t —list Сформировать список содержимого архива
-u —update Обновить архив более новыми файлами с тем же именем
-x —extract Извлечь файлы из архива

При определении каждой функции используются параметры, которые регламентируют выполнение конкретных операций с tar-архивом:

Параметр Длиннный
формат
Описание
-C dir —directory=DIR Сменить директорию перед выполнением операции на dir
-f file —file Вывести результат в файл (или на устройство) file
-j —bzip2 Перенаправить вывод в команду bzip2
-p —same-permissions Сохранить все права доступа к файлу
-v —verbose Выводить подробную информацию процесса
—totals Выводить итоговую информацию завершенного процесса
-z —gzip Перенаправить вывод в команду gzip

А дальше рассмотрим примеры того, как может применяться команда tar Linux.

Как пользоваться tar

1. Создание архива tar

С помощью следующей команды создается архив archive.tar с подробным выводом информации, включающий файлы file1, file2 и file3:

tar —totals —create —verbose —file archive.tar file1 file2 file3

Но длинные опции и параметры можно заменить (при возможности) однобуквенными значениями:

tar —totals -cvf archive.tar file1 file2 file3

2. Просмотр содержимого архива

Следующая команда выводит содержимое архива, не распаковывая его:

tar -tf archive.tar

3. Распаковка архива tar Linux

Распаковывает архив test.tar с выводом файлов на экран:

tar -xvf archive.tar

Чтобы сделать это в другой каталог, можно воспользоваться параметром -C:

tar -C «Test» -xvf archive.tar

3. Работа со сжатыми архивами

Следует помнить, что tar только создаёт архив, но не сжимает. Для этого используются упомянутые компрессорные утилиты bzip2 и gzip. Файлы, сжатые с их помощью, имеют соответствующие расширения .tar.bz2 и .tar.gz. Чтобы создать сжатый архив с помощью bzip2, введите:

tar -cjvf archive.tar.bz2 file1 file2 file3

Синтаксис для gzip отличается одной буквой в параметрах, и меняется окончание расширения архива:

tar -czvf archive.tar.gz file1 file2 file3

При распаковке tar-архивов с таким расширением следует указывать соответствующую опцию:

tar -C «Test» -xjvf arhive.tar.bz2

tar -xzvf archive.tar.gz

На заметку: архиватор tar — одна из немногих утилит в GNU/Linux, в которой перед использованием однобуквенных параметров, стоящих вместе, можно не ставить знак дефиса.

Выводы

В этой статье была рассмотрена команда tar Linux, которая используется для архивации файлов и поставляется по умолчанию во всех дистрибутивах. В её возможности входит создание и распаковка архива файлов без их сжатия. Для сжатия утилита применяется в связке с популярными компрессорами bzip2 и gzip.

Источник

tar with relative paths

I try to create an archive with tar using relative paths. I use the following command:

But the archived files still have absolute paths. How can I use tar with relative paths?

4 Answers 4

is expanded by the shell. Don’t use

(tar will include webapps/zers/wp-content/plugins/my-page-order path) or

(tar will include my-page-order path)

Or just cd first.

is expanded by shell. What matters is that -C changes current working directory as explained in anwer by Lekensteyn.

here does not matter at all.

-C new_cwd changes the current working directory to new_cwd . The following arguments are then evaluated relative to new_cwd .

The non GNU solution if tar has no -z option, just to mention:

EDIT (with && and without rm ):

/webapps/zers/wp-content/plugins/my-page-order with output to

/files/wp/my-page-order.tar.gz ; your command archives

/files/wp/my-page-order . (3) Thanks for editing your answer to explain why you used gzip .

I tried with wildcard * but it gave me absolute paths as well so I tried later like this:

This archives (compresses) all the given files without absolute paths.

It appears that with the dot ( . ) works well. Don’t know why exactly. I hope the answer helps.

Not the answer you’re looking for? Browse other questions tagged tar or ask your own question.

Linked

Hot Network Questions

Subscribe to RSS

To subscribe to this RSS feed, copy and paste this URL into your RSS reader.

site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.10.8.40416

By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.

Источник

Tar a directory, but don’t store full absolute paths in the archive

I have the following command in the part of a backup shell script:

When I list the contents of the archive, I get:

But I would like to remove the part /var/www/site1 from directory and file names within the archive, in order to simplify extraction and avoid useless constant directory structure. Never know, in case I would extract backuped websites in a place where web data weren’t stored under /var/www .

For the example above, I would like to have :

So, that when I extract, files are extracted in the current directory and I don’t need to move extracted files afterwards, and so that sub-directory structures is preserved.

There are already many questions about tar and backuping in stackoverflow and at other places on the web, but most of them ask for dropping the entire sub-directory structure (flattening), or just add or remove the initial / in the names (I don’t know what it changes exactly when extracting), but no more.

After having read some of the solutions found here and there as well as the manual, I tried :

But none of them worked the way I want. Some do nothing, some others don’t archive sub-directories anymore.

It’s inside a backup shell script launched by a Cron, so I don’t know well, which user runs it, what is the path and the current directory, so always writing absolute path is required for everything, and would prefer not changing current directory to avoid breaking something further in the script (because it doesn’t only backup websites, but also databases, then send all that to FTP etc.)

How to achieve this?

Have I just misunderstood how the option -C works?

Источник

Excluding directory when creating a .tar.gz file

I have a /public_html/ folder, in that folder there’s a /tmp/ folder that has like 70gb of files I don’t really need.

Now I am trying to create a .tar.gz of /public_html/ excluding /tmp/

This is the command I ran:

The tar is still being created, and by doing an ls -sh I can see that MyBackup.tar.gz already has about 30gb, and I know for sure that /public_html/ without /tmp/ doesn’t have more than 1GB of files.

What did I do wrong?

10 Answers 10

Try removing the last / at the end of the directory path to exclude

Try moving the —exclude to before the include.

Yes, remove the trailing / and (at least in ubuntu 11.04) all the paths given must be relative or full path. You can’t mix absolute and relative paths in the same command.

will not exclude logs directory but

The correct command for exclude directory from compression is :

Make sure to put —exclude before the source and destination items.

and you can check the contents of the tar.gz file without unzipping :

You can also exclude more than one using only one —exclude . Like this example:

In —exclude= you must finish the directory name without / and must in between MyBackup.tar.gz and /home/user/public_html/

tar -pczf —exclude /path/to/exclude —exclude /another/path/to/exclude/* /path/to/include/ /another/path/to/include/*

Tested in Ubuntu 19.10.

  1. The = after exclude is optional. You can use = instead of space after keyword exclude if you like.
  2. Parameter exclude must be placed before the source.
  3. The difference between use folder name (like the 1st) or the * (like the 2nd) is: the 2nd one will include an empty folder in package but the 1st will not.

Источник

How do I tar a directory of files and folders without including the directory itself?

What if I just want to include everything (including any hidden system files) in my_directory, but not the directory itself? I don’t want:

20 Answers 20

Use the -C switch of tar:

The -C my_directory tells tar to change the current directory to my_directory , and then . means «add the entire current directory» (including hidden files and sub-directories).

Make sure you do -C my_directory before you do . or else you’ll get the files in the current directory.

should do the job in one line. It works well for hidden files as well. «*» doesn’t expand hidden files by path name expansion at least in bash. Below is my experiment:

You can also create archive as usual and extract it with:

Have a look at —transform / —xform , it gives you the opportunity to massage the file name as the file is added to the archive:

Transform expression is similar to that of sed , and we can use separators other than / ( , in the above example).
https://www.gnu.org/software/tar/manual/html_section/tar_52.html

TL;DR (no ./ and no ./file1 !)

With some conditions (archive only files, dirs and symlinks):

Explanation

The below unfortunately includes a parent directory ./ in the archive:

You can move all the files out of that directory by using the —transform configuration option, but that doesn’t get rid of the . directory itself. It becomes increasingly difficult to tame the command.

You could use $(find . ) to add a file list to the command (like in magnus’ answer), but that potentially causes a «file list too long» error. The best way is to combine it with tar’s -T option, like this:

Basically what it does is list all files ( -type f ), links ( -type l ) and subdirectories ( -type d ) under your directory, make all filenames relative using -printf «%P\n» , and then pass that to the tar command (it takes filenames from STDIN using -T — ). The -C option is needed so tar knows where the files with relative names are located. The —no-recursion flag is so that tar doesn’t recurse into folders it is told to archive (causing duplicate files).

If you need to do something special with filenames (filtering, following symlinks etc), the find command is pretty powerful, and you can test it by just removing the tar part of the above command:

For example if you want to filter PDF files, add ! -name ‘*.pdf’

Non-GNU find

The command uses printf (available in GNU find ) which tells find to print its results with relative paths. However, if you don’t have GNU find , this works to make the paths relative (removes parents with sed ):

This Answer should work in most situations. Notice however how the filenames are stored in the tar file as, for example, ./file1 rather than just file1 . I found that this caused problems when using this method to manipulate tarballs used as package files in BuildRoot.

One solution is to use some Bash globs to list all files except for .. like this:

This is a trick I learnt from this answer.

Now tar will return an error if there are no files matching . * or .[^.]* , but it will still work. If the error is a problem (you are checking for success in a script), this works:

Though now we are messing with shell options, we might decide that it is neater to have * match hidden files:

This might not work where your shell globs * in the current directory, so alternatively, use:

This one worked for me and it’s include all hidden files without putting all files in a root directory named «.» like in tomoe’s answer :

If it’s a Unix/Linux system, and you care about hidden files (which will be missed by *), you need to do:

I don’t know what hidden files look like under Windows.

I would propose the following Bash function (first argument is the path to the dir, second argument is the basename of resulting archive):

You can run it in this way:

and it will generate the archive my_archive.tar.gz within current directory. It works with hidden (.*) elements and with elements with spaces in their filename.

Command

to create a standard archive file.

find my_directory/ -maxdepth 1 -printf «%P\n» | tar -cvf my_archive.tar -C my_directory/ -T —

Packed files and dirs are in the root of the archive without path info and deeper files have relative path.
There are no weird looking ‘./’ in front of files and dirs. (‘./file’)
No special files ‘.’ are included.

It seems that another tool, like find or ls ( ls -A -1 ) is needed to accomplish these goals and tar using just its arguments is unable to pick files and create an archive with such requirements.

Using above command creates an archive tar file which can be further processed or delivered to someone without looking weird or needing an explanation or a tool to unpack.

Arguments description

-maxdepth 1
Descend at most 1 level — No recursing.
-printf
print format on the standard output
%P File’s name with the name of the starting-point under which it was found removed.
\n Newline
printf does not add a newline at the end of the string. It must be added here

tar:
-C DIR , —directory=DIR
change to directory DIR

-T FILE , —files-from=FILE
get names to extract or create from FILE

that FILE from above is the standard input, from the pipe

Comments on other solutions.

The same result might be achieved using solution described by @aross.
The difference with the solution here is in that which tool is doing the recursing. If you leave the job to find , every filepath name, goes through the pipe. It also sends all directory names, which tar with —no-recursion ignores or adds as empty ones followed by all files in each directory. If there was unexpected output as errors in file read from find , tar would not know or care what’s going on.
But with further checks, like processing error stream from find, it might be a good solution where many options and filters on files are required.
I prefer to leave the recursing on tar, it does seem simpler and as such more stable solution.
With my complicated directory structure, I feel more confident the archive is complete when tar will not report an error.

Another solution using find proposed by @serendrewpity seems to be fine, but it fails on filenames with spaces. Difference is that output from find supplied by $() sub-shell is space-divided. It might be possible to add quotes using printf, but it would further complicate the statement.

There is no reason to cd into the my_directory and then back, while using ../my_archive.tar for tar path, because TAR has -C DIR , —directory=DIR command which is there just for this purpose.

Using . (dot) will include dots

Using * will let shell supply the input file list. It might be possible using shell options to include dot files. But it’s complicated. The command must be executed in shell which allows that. Enabling and disabling must be done before and after tar command. And it will fail if root dir of future archive contains too many files.

That last point also applies to all those solutions which are not using pipe.

Most of solutions are creating a dir inside which are the files and dirs. That is barely ever desired.

Источник

Читайте также:  Microsoft ���������� ���� linux
Оцените статью