Tar recursive compare with original folder - linux

I have a .tgz file made with tar cvzf tartest.tgz tester/* and if I list the tar with tar --list -f tartest.tgz file, I have the following structure
tester/2017-08-02_131404.png
tester/cfg.pdf
tester/tests/
tester/tests/1.png
tester/tests/2.png
tester/tests/3.png
tester/tests/4.png
tester/tests/5.png
If I compare the tar with the original folder by using tar -df tartest.tgz tester/*, everything ok, no problems, no errors
If I add the file 20171006_183137.png in the tester folder, and retry, I get an error, as expected:
tar: tester/20171006_183137.png: Not found in archive
tar: Exiting with failure status due to previous errors
If I add the file 20171006_183137.png in the tester/tests folder, and retry, I get no error and blank output.
If I add -v option during last test, I just get the list of the files in the tar.
Is there a way to recursive compare tar with original folder and subfolders?

According to this site, tar behaves as intended.
You should note again that while --compare (-d) does cause tar to
report back on files in the archive that do not exist in the file
system, tar will ignore files in the active file system that do not
exist in the archive.
The error you are getting for tar -df tartest.tgz tester/* is indeed an error (!) not a message like »archive and directory differ«. tar does not know how to treat files that are not in the archive.
If you also want to compare the other way around, you could use the method described in this answer (mount or unpack the archive and use diff -r against the original directory).
If you are only interested in a file's existence and not content, access dates, and so on, you could list the file names from the archive and from the original directory and compare them with diff:
diff <(tar -tf tartest.tgz | sort) <(find tester/ | sort)
The command works only if there are no file names with linebreaks in them.
Use diff -y or the comm command for a more readable output.

Related

Tar command keeps bundling up entire directory path

I have a few sub-directories with files inside each of them in /home/user/archived/myFiles that I'm trying to bundle into a single tar file. The issue is, it keeps bundling a full directory path instead of just everything in the myFiles folder.
When I untar the file, I just want all the bundled sub-directories/files inside to appear in the directory I extracted the file rather than having to go through a series of folders that get created.
Instead, when I currently untar the file, I get a "home" folder and I have to go through /home/user/archived/myFiles to reach all the files.
I tried using the -C flag that I saw suggested online here Tar a directory, but don't store full absolute paths in the archive where you insert parameters for the full directory minus the last folder, and then the name of the last folder which contains all the stuff you want bundled. But the tar command doesn't work as I get a no such file or directory error.
#!/bin/bash
archivedDir="/home/user/archived/myFiles"
tar -czvf "archived-files.tar.gz" "${archivedDir}"/*
rm -vrf "${archivedDir}"/*
# Attempt with -C flag
#tar -cvf "${archivedDir}/archived-files.tar.gz" -C "${archivedDir}" "/*"
So for example, if I did an ls on /home/user/archived/myFiles, and it listed two directories called folderOne and folderTwo, and I ran this bash script and did an ls on /home/user/archived/myFiles again, that directory should only contain archived-files.tar.gz.
If I extracted the tar file, then folderOne and folderTwo would appear.
As I explain already here you should first change to this directory and then create the archive.
So change you script to something like:
archivedDir="/home/user/archived/myFiles"
cd $archivedDir
tar -czvf "../archived-files.tar.gz" *
This will create the archive in upper directory so you will not remove it with the next command.
the extraction should be something like:
archivedDir="/home/user/archived/myFiles"
cd $archivedDir
tar -xzvf "../archived-files.tar.gz"

tar: Cowardly refusing to create an empty archive

I use the following tar command to try to backup my entire file system
tar -cvpzf test/backup.tar.gz --exclude=/test
And I receive the following error message
tar: Cowardly refusing to create an empty archive
Try 'tar --help' or 'tar --usage' for more information.
Can somebody point me in the right direction as to how to use tar and explain why it's trying to create an empty archive?
You defined what to exclude, but didn't define what you actually want in the archive. Supply at least one path. If you want entire filesystem, then tar -c....... /

Structure of .tar files

I am trying to run some benchmarks which take in input a tar file.
Now there is a runme.sh inside the tar file and that needs to be modified and the folder has to be made a .tar again.
The original benchmark works, but the modifies one doesn't. I believe that it is a problem with the file format.
Note : My modification is not creating the problem. If I just uncompress the working tar and tar it again without modification, it does not work. Surprisingly the size of the new file changes.
What I tried :
file command on the working and non-working tar files.
Both returned same POSIX tar archive
Tried to run the command tar cvf folder_name.tar folder_name/
Does not work.
What works :
I am on Ubuntu (14.04) and I double clicked on the tar, directly edited the file I wanted and updated it. This works, but is not a feasible solution as I have a large number of files and I want to write a script to automate it.
Screenshot of how it works with GUI :
Does the original tar file include the top-level directory name? It doesn't look like it from your screenshot. If you re-create the tar file with a top level directory, as indicated by point 2 in the things you tried, the structure won't be the same, and whatever program is trying to consume the tar file won't be able to parse it.
How do you test "If I just uncompress the working tar and tar it again without modification, it does not work." In a GUI or in a shell? If in a shell - what exact commands do you use?
In a shell, you can get the contents of the tarball with the command tar -tf filename.tar. If all the files it lists starts with the same folder name, your tarball includes a top level directory. If it just lists various files and subdirectories, it doesn't. (Tarballs that don't are an abomination, but if whatever you are using them for requires it, you'll just have to cope.)
I'm guessing that if you do this on your original tar file and your modified, non-working tar file, the results will differ.
The following should work in a shell if you have/need a tarball without a toplevel directory:
$ mkdir workdir
$ cd workdir
$ tar -xf ../tarball.tar
<edit your file however you like>
$ tar -cf ../tarball-new.tar *
$ cd ..
$ rm -r workdir
In case you have/need a tarball with a toplevel directory, the following should suffice:
$ tar -xf ../tarball.tar
$ cd toplevel_directory
<edit your file however you like>
$ cd ..
$ tar -cf tarball-new.tar toplevel_directory
$ rm -r toplevel_directory
Edit: I'm glad it worked for you. The point is, of course, that tar includes the paths of the files it stores, not just the filenames. So if you need a flat list of files, you need to run tar in the directory containing those files, giving all of them as arguments to tar. If you try to take the shortcut of going up a level and only specifying the directory name to pack up, tar will include the directory name in the archive.

Extract tar archive excluding a specific folder and its contents

With PHP I am using exec("tar -xf archive.tar -C /home/user/target/folder") to extract the contents of a specific archive (archive.tar) into the target directory (/home/user/target/folder), so that all existing contents of the target directory will be overwritten by the new ones that are contained in the archive.
It works fine and all files in the target directory are being overwritten after extract, but there is one directory in the archive that I would like to omit (from extracting and thus overwriting the existing one in the target folder)...
For example, the archive.tar contains:
folderA/
folderB/
folderC/
folderD/
fileA.php
fileB.php
fileC.xml
How could I extract (and overwrite) all except (for example) folderC/? In other words, I want folderC and its contents to remain intact in the user's directory and not be overwritten by the one contained in the tar archive.
Any suggestions?
(Tar on the hosting server is GNU version 1.23.)
You can use '--exclude' to omit a folder:
tar -xf archive.tar -C /home/user/target/folder" --exclude="folderC"
There is the --exclude PATTERN option in the tar tool.
Check: tar on linuxcommand.org
To be on the safe side, you could remove all write permissions from the folder. For example:
$ chmod 000 folderC/
An then do a normal tar extract (as regular user). You'll get some error messages on console, but your folder will remain untouched.... At the end of the tar, change back your folder original permissions. For example:
$ chmod 775 folderC/
Of course '--exclude' tar option is the right solution to this particular problem, but, if you are not completely 100% sure about a command syntax, and yor're handling critical data, my solution puts you on the safe side :-).
Write --exclude='./folder' at the beginning of the tar command.
In your case that is,
exec("tar -x --exclude='./C' -f archive.tar -C /home/user/target/folder")

using tar to extract latest .gz file into another directory

Below is my code
#!/bin/bash
# Location for backups to be saved.
EXTRACTTO=/opt/test_script
#stores the latest .gz file to be extracted
EXTRACTFROM= ls -t /opt/scripts/AXDB1.clean_pof_backup* | head -1
echo $EXTRACTFROM
tar -xf $EXTRACTFROM -C $EXTRACTTO
EXTRACTTO contains the path where I want to extract my .gz files to.
EXTRACTFROM contains the latest .gz file, which will be extracted.
However when I pass this variables which contains directory path, in tar command
it gives invalid directory error.
Can someone tell how can I accomplish my task here?
Judging from the error message, it seems that EXTRACTTO is incorrect. Print it out and try running the tar command manually.

Resources