Can tar extraction erase brother directory ? - linux

I made several backups on different directories with Backup Manager. Eg: /home/user1 /home/user2...
It gives me some tar files. The content of a tar file looks like :
home/user1/
home/user1/.profile
home/user1/.bash_history
home/user1/.bash_logout
...
I tried to test the restoration with something like :
tar -xvzf home.user1.tar.gz -C home/user1
But the command above recreate all the structure inside the choosen directory. That gives /home/user1/home/user1/filname1.
So I guess I should use the command specifying the home directory (/home) instead of the user directory. But is there any risk to erase other user's directories in /home ?
Thks for your time.

Actually tar does not erase data as a default. But any files that are contained within the tar archive will overwrite files of the same name if they are already present. Likewise a sub-directory's contents will not be overwritten if the tar archive does not contain files matching them.
mkdir -p foo/bar/
touch foo/file1 foo/bar/file1
tar -cf foo.tar foo/
rm -rf foo
mkdir -p foo/bar/
touch foo/file2 foo/bar/file2
tar -xf foo.tar
ls foo foo/bar/
As once can see both file1 and file2 are present and the newly unarchived directory did not overwrite the old. Here is the output of ls from my system:
foo:
bar file1 file2
foo/bar/:
file1 file2

Related

Loop through directory and zip specific folder without parent path

I'm trying to make a bash script to loop through all folder in directories, and individually zip just the folder I want without all path and choose where to zip theme.
#!/bin/bash
for dir in /MyPersonalFolder/*/*/WhatIWantFolder
do
folder_number=$(basename ${dir%/*}) ### basename get the name of this folder [*] 'folder have numbers' /MyPersonalFolder/*/[*]/WhatIWantFolder
sudo tar -cf "${folder_number}-WhatIWantFolder".tar.gz --absolute-names "$dir"
mkdir -p ./backup-theme/ && sudo mv "${folder_number}-theme".tar.gz $_ ### I use this to move zipped folder to specific directory if i can choose where to zip file in the zip command line it's better
done
I can zip the folder I want, but the output zip file comes with this content:
/MyPersonalFolder/0001/0001/WhatIWantFolder
But what I need is to output the file with this path:
0001/
|___WhatIWantFolder/
I tried to change "$dir" in this line
sudo tar -cf "${folder_number}-WhatIWantFolder".tar.gz --absolute-names "$dir"
with basename ${dir%/*}
sudo tar -cf "${folder_number}-WhatIWantFolder".tar.gz --absolute-names "basename ${dir%/*}"
tar not found the folder it's come with errors
tar: e0001: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors
You can cd to another directory while running tar using the --cd option.
#!/bin/bash
for dir in MyPersonalFolder/*/*/WhatIWantFolder; do
parent="${dir%/*/*}"
subdir="${dir#*/*/*}"
outfile="backup-theme/${subdir/\//-}.tar.gz"
tar --cd "$parent" -cvzf "$outfile" "$subdir"
done
The directory structure of the tar file would look something like this:
tar -tf backup-theme/0001-WhatIWantFolder.tar.gz
0001/WhatIWantFolder/
0001/WhatIWantFolder/f1

Download, extract and copy file from a folder that has a version in its name

I'm writing a bash script that downloads an compressed archive from an universal URL (in which new release of the software will automatically be presented), extracts it and copies a file called wimboot to a folder.
This is what I currently have:
sudo curl http://git.ipxe.org/releases/wimboot/wimboot-latest.tar.gz -o ./wimboot.tar.gz
sudo tar -zxvf ./wimboot.tar.gz #Extracts into a folder called "wimboot-2.5.2-signed", in it is the file I need ("wimboot").
cd ./wimboot*/
sudo cp wimboot /my-folder/
But this doesn't work. Is there a method that will allow me to do this?
You can ask tar for a file listing (-t option), which you can then grep for wimboot -- that should give you the relative path to the file also. A naive first try would be something like:
src_file=$(tar tf wimboot.tar.gz | grep wimboot)
cp "$src_file" my_folder/
But you will probably want to add some error checking and stuff to that. And probably a more complicated grep expression to ensure you get the one thing you're after.
There's also no need to extract the entire archive. You can just ask tar to extract the file you're interested in:
tar zxf wimboot.tar.gz "$src_file"
I've built on top of the other answers and this worked for me:
#Create a temporary folder, this folder must be empty!
sudo mkdir temp
#Download the archive and save it in the temporary folder.
sudo curl http://git.ipxe.org/releases/wimboot/wimboot-latest.tar.gz -o ./temp/wimboot-latest.tar.gz
#Extract the downloaded archive to the temporary folder.
sudo tar xvf ./temp/wimboot-latest.tar.gz -C ./temp
#Search for and copy files with the name "wimboot" to the web directory.
sudo find ./temp/ -name 'wimboot' -exec cp {} /var/www/ \;
#Delete the temporary folder.
sudo rm -Rf temp
I do not recommend this for large archives.

how to rename files you put into a tar archive using linux 'tar'

I'm trying to create a tar archive with a couple files, but rename those files in the archive. Right now I have something like this:
tar -czvf file1 /some/path/to/file2 file3 etc
But I'd like to do something like:
tar -czvf file1=file1 /some/path/to/file2=file2 file3=path/to/renamedFile3 etc=etc
Where, when extracted into directory testDir, you would see the files:
testDir/file1
testDir/file2
testDir/path/to/renamedFile3
testDir/etc
How can I do this?
You can modify filenames (among other things) with --transform. For example, to create a tape archive /tmp/foo.tar, putting files /etc/profile and /etc/bash.bashrc into it while also renaming profile to foo, you can do the following:
tar --transform='flags=r;s|bar|foo|' -cf file.tar file1 file2 bar fubar /dir/*
Results of the above is that bar is added to file.tar as foo.
The r flag means transformations are applied to regular files only. For more information see GNU tar documentation.
You can use --transform multiple times, for example:
tar --transform='flags=r;s|foo|bar|' --transform='flags=r;s|baz|woz|' -cf file.tar /some/dir/where/foo/is /some/dir/where/baz/is /other/stuff/* /dir/too
With --transform, there's no need to make a temporary testDir first. To prepend testDir/ to everything in the archive, match the beginning anchor ^:
tar --transform "s|file3|path/to/renamedFile3|" \
--transform "flags=r;s|^|testDir/|" \
-czvf my_archive.tgz file1 /some/path/to/file2 file3 etc
The r flag is critical to keep the transform from breaking any symlink targets in the archive (which also match ^).
We can refer to the man tar, the -O option is the best choice since files can be written to standard out.
-O (x, t modes only) In extract (-x) mode, files will be written to
standard out rather than being extracted to disk. In list (-t)
mode, the file listing will be written to stderr rather than the
usual stdout.
here are the examples:
# 1. without -O
tar xzf 20170511162930.db.tar.gz
# result: 20170511162930.db
# 2. with -O
tar xzf 20170511162930.db.tar.gz -O > latest.db
# result: latest.db
After not liking any solution that I've found, I've just written tarlogs.py, which lets you specify arbitrary names for tar entries. Each tar entry is constructed from one (or several) regular (or gzipped) inputs. You can also add directories, which will be recursed into as with regular tar. So in your case,
tarlogs.py -o file1 -i /some/path/to/file2 -o file2 -i file3 -o path/to/renamedFile3 -o /etc >output.tar
(-o with no -i inputs simply uses the output path as input, with no renaming)
This question has been up for a while, but for anyone who's looking for another suitable solution:
I've created a fork of the original GNU tar utility with additional support for file name mapping.
Usage example:
> touch myfile.txt
> tar cf file.tar ':myfile.txt:dir/inside/tar/newname.txt'
> tar tvf file.tar
-rw-rw-r-- user/user 0 2022-02-12 14:27 dir/inside/tar/newname.txt
The feature is triggered by prefixing file names with a colon (:) as shown above. A second colon functions as a separator between the source file location and the desired file name inside the archive.
:[source file]:[desired name inside the tar]
This feature is compatible with the -T (input list from file) flag.
How to compile it
> git clone https://github.com/leso-kn/tar
> cd tar
> ./bootstrap
> ./configure
> make -j4
# Run it
> src/tar --version

linux shell tar unwanted extra directories

I have the following problem:
I have directorties a/b/c and inside c many text files.
I want to make a .tar.gz file in drectory a/mydir with the c directory inside and then unzip it to that same directory to create a/mydir/c (with all the files inside)
I am at directory a and run: (shell)
~:$ tar -czf mydir/output.tar.gz b/c
~:$ tar -zxf mydir/output.tar.gz -c mydir
but the result is directories a/mydir/b/c (with the files inside)
The problem is I don't want directory b in the middle, just c with all its contents
This works for me. Create data
mkdir -p a/b/c
echo 42 > a/b/c/file.dat
Archive
tar zc -f c.tar.gz -C a/b c
created a/b/c directories, from directory a kindly try this command.
so the file under b/c/files were done out.tar.gz
new directory "mydir" create under "b" and files extracted too.
out.tar.gz removed from "a".
# tar -cvzf out.tar.gz b/c/* ; mkdir -p b/mydir ; tar -xvzf out.tar.gz -C b/mydir/ ; rm -rf out.tar.gz
Thanks!

How do I tar a directory without retaining the directory structure?

I'm working on a backup script and want to tar up a file directory:
tar czf ~/backup.tgz /home/username/drupal/sites/default/files
This tars it up, but when I untar the resulting file, it includes the full file structure: the files are in home/username/drupal/sites/default/files.
Is there a way to exclude the parent directories, so that the resulting tar just knows about the last directory (files)?
Use the --directory option:
tar czf ~/backup.tgz --directory=/home/username/drupal/sites/default files
Hi I've a better solution when enter in the specified directory it's impossible (Makefiles,etc)
tar -cjvf files.tar.bz2 -C directory/contents/to/be/compressed .
Do not forget the dot (.) at the end !!
cd /home/username/drupal/sites/default/files
tar czf ~/backup.tgz *
Create a tar archive
tar czf $sourcedir/$backup_dir.tar --directory=$sourcedir WEB-INF en
Un-tar files on a local machine
tar -xvf $deploydir/med365/$backup_dir.tar -C $deploydir/med365/
Upload to a server
scp -r -i $privatekey $sourcedir/$backup_dir.tar $server:$deploydir/med365/
echo "File uploaded.. deployment folders"
Un-tar on server
ssh -i $privatekey $server tar -xvf $deploydir/med365/$backup_dir.tar -C $deploydir/med365/
To gunzip all txt (*.txt) files from /home/myuser/workspace/zip_from/
to /home/myuser/workspace/zip_to/ without directory structure of source files use following command:
tar -P -cvzf /home/myuser/workspace/zip_to/mydoc.tar.gz --directory="/home/myuser/workspace/zip_from/" *.txt
If you want to tar files while keeping the structure but ignore it partially or completely when extracting, use the --strip-components argument when extracting.
In this case, where the full path is /home/username/drupal/sites/default/files, the following command would extract the tar.gz content without the full parent directory structure, keeping only the last directory of the path (e.g. files/file1).
tar -xzv --strip-components=5 -f backup.tgz
I've found this tip on https://www.baeldung.com/linux/tar-archive-without-directory-structure#5-using-the---strip-components-option.
To build on nbt's and MaikoID's solutions:
tar -czf destination.tar.gz -C source/directory $(ls source/directory)
This solution:
Includes all files and folders in the directory
Does not include any of the directory structure (or .) in the final product
Does not require you to change directories.
However, it requires the directory to be given twice, so it may be most useful in another script. It may also be less efficient if there are a lot of files/folders in source/directory. Adjust the subcommand as necessary.
So for instance for the following structure:
|- source
| |- one
| `- two
`- working
the following command:
working$ tar -czf destination.tar.gz -C ../source $(ls ../source)
will produce destination.tar.gz where both one and two (and sub-files/-folders) are the first items.
This worked for me:
gzip -dc "<your_file>.tgz" | tar x -C <location>
For me -C or --directory did not work, I use this
cd source/directory/or/file
tar -cvzf destination/packaged-app.tgz *.jar
# this will put your current directory to what it previously was
cd -
Kindly use the below command to generate tar file without directory structure
tar -C <directoryPath> -cvzf <Path of the tar.gz file> filename1 filename2... filename N
eg:
tar -C /home/project/files -cvzf /home/project/files/test.tar.gz text1.txt text2.txt
tar -Cczf ~/backup.tgz /home/username/drupal/sites/default/files
-C does the cd for you

Resources