0

I'm looking for a way to create a .tar.gz file from a directory but I have some doubts. I'm know that the command for create the file is:

tar -zcvf /path/to/compressed/file.tar.gz /path/to/compress 

And then I will get a file.tar.gz but this keep the path to the original sources. So this is what I'm looking for:

  • Should be compress as .tar.gz
  • If it's possible shouldn't keep the path to the compressed directory I mean I only needs the compress directory and its content .If I uncompress the file under Windows for example I'll get /path[folder]/to[folder]/compress[folder+content] and I just want the latest
  • If it's possible can I ommit some directories? Example I like to compress app/ folder and its content is:

    drwxrwxr-x  6 ubuntu ubuntu  4096 Feb 24 14:48 ./
    drwxr-xr-x 10 ubuntu ubuntu  4096 Feb 26 22:33 ../
    -rw-rw-r--  1 ubuntu ubuntu   141 Jan 29 06:07 AppCache.php
    -rw-rw-r--  1 ubuntu ubuntu  2040 Feb 24 14:48 AppKernel.php
    -rw-rw-r--  1 ubuntu ubuntu   267 Jan 29 06:07 autoload.php
    -rw-r--r--  1 root   root   94101 Feb 19 21:09 bootstrap.php.cache
    drwxrwxrwx  4 ubuntu ubuntu  4096 Feb 25 16:44 cache/
    -rw-rw-r--  1 ubuntu ubuntu  3958 Feb 24 14:48 check.php
    drwxrwxr-x  2 ubuntu ubuntu  4096 Feb 24 14:48 config/
    -rwxrwxr-x  1 ubuntu ubuntu   867 Jan 29 06:07 console*
    -rw-rw-r--  1 ubuntu ubuntu  6148 Jan 29 06:07 .DS_Store
    -rw-rw-r--  1 ubuntu ubuntu   143 Jan 29 06:07 .htaccess
    drwxrwxrwx  2 ubuntu ubuntu  4096 Feb 24 14:48 logs/
    -rw-rw-r--  1 ubuntu ubuntu  1118 Jan 29 06:07 phpunit.xml.dist
    drwxrwxr-x  5 ubuntu ubuntu  4096 Jan 29 06:07 Resources/
    -rw-rw-r--  1 ubuntu ubuntu 30404 Feb 24 14:48 SymfonyRequirements.php
    

    But I want to leave out cache/, logs/ directories and bootstrap.php.cache file, how? Is that possible?

  • I need to append the current date (DD/MM/YYYY-H:M:S) to the file name, how?

Can I get some advise or help on this? I'm planning to add this to a Bash script so it will works as a bash script and not as a command line

Update: testing inside the script

Following @Ariel suggestion I have added this line to a bash script:

read -e -p "Enter the directory to compress: " -i "/var/www/html/" directory
read -e -p "Enter the filename: " filename
FILENAME = "$filename-`date +%d-%m-%Y-%X`.tgz"

cd "$directory"
tar -zcvf /home/$FILENAME --exclude cache --exclude logs --exclude bootstrap.php.cache --exclude composer.lock --exclude vendor

But I'm getting this error:

Enter the directory to compress: /var/www/html/lynxoft/apps/checkengine/
Enter the filename: checkengine
/usr/local/bin/script-task: line 109: FILENAME: command not found
tar: Cowardly refusing to create an empty archive

Why FILENAME is treat as a command and not as a var as docs says?

Update 2: still compressing the whole path

I have fixed some issues thanks to users comments and lines on the script looks likes this:

read -e -p "Enter the directory to compress: " -i "/var/www/html/" directory
read -e -p "Enter the filename: " filename
FILENAME="$filename"-$(date +%d-%m-%Y-%T).tgz

cd "$directory/.."
tar -zcvf /home/$FILENAME "$directory" --exclude="*cache*" --exclude=logs --exclude=bootstrap.php.cache --exclude=composer.lock --exclude=vendor --exclude=.git

The only remaining issue is that compressed file still having the whole path and not just the end directory. For example:

Enter the directory to compress: /var/www/html/lynxoft/apps/checkengine/
Enter the filename: file

That result in file-28-02-2015-17:44:32.tgz but content inside the compressed file still having the whole path /var/www/html/lynxoft/apps/checkengine/, why?

  • 1
    tar -zcvf "/path/to/compressed/$(date +%d/%m/%Y-%X).tar.gz" -C /path/to/compress/ ./ --exclude="*cache*" --exclude=logs (read man tar) – Costas Mar 1 '15 at 19:04
  • @Costas I've tried your solution also but get this tar (child): /home/checkengine(date +%d/%m/%Y-%X).tar.gz: Cannot open: No such file or directory error on console (also tried from the script) why? – ReynierPM Mar 1 '15 at 20:19
  • You prolly forgot the $ before (date...). Also, @Costas - are you trying to create a file with /s in its name ? – don_crissti Mar 1 '15 at 20:23
  • @ReynierPM you should not leave spaces in the shell variable declarations! Use exactly FILENAME="..." – Ariel Mar 1 '15 at 20:30
  • @Ariel fixed that one but still getting this: tar: Cowardly refusing to create an empty archive – ReynierPM Mar 1 '15 at 20:31
2

Just cd to the folder from where you want the tarball tress structure to start, and use relative paths! So for instance:

# Note, one folder above
cd /path/to/compress/..
# Tell tar to compress the relative path    
tar -zcvf /path/to/compressed/file.tar.gz compress

When you uncompress it, it will create the compress folder in the current working directory.

You can exclude files or folders using the --exclude <PATTERN> option, and add a date in the filename with date +FORMAT, for instance:

FILENAME="file-`date +%d-%m-%Y-%T`.tgz"
tar -zcvf /path/to/compressed/$FILENAME --exclude cache --exclude logs --exclude bootstrap.php.cache compress
  • can you take a look to my latest edit? – ReynierPM Mar 1 '15 at 20:18
  • 1
    Note that %X = locale's time representation; on some systems that means 11:43:11 AM. So quote your variables (and preferably use %T). – don_crissti Mar 1 '15 at 20:20
  • @don_crissti did you see my latest edit? I have changed the FILENAME to FILENAME = "$filename"-$(date +%d-%m-%Y-%T).tgz but still getting the same issue /usr/local/bin/script-task: line 109: FILENAME: command not found tar: Cowardly refusing to create an empty archive why? Any advice? – ReynierPM Mar 1 '15 at 20:30
  • @don_crissti good point, i fixed my answer with that improvement now, thanks – Ariel Mar 1 '15 at 20:31
  • @ReynierPM - wrong quoting. It's tar -zcvf /path/to/compressed/"$FILENAME" ... but then your FILENAME="$filename"-$(date +%d-%m-%Y-%T).tgz is wrong too, it has to be FILENAME="$filename-$(date +%d-%m-%Y-%T).tgz"... or if you want to include the date in the argument passed to tar see my answer. – don_crissti Mar 1 '15 at 21:59
1

With gnu tar you could use:

--transform=EXPRESSION, --xform=EXPRESSION
      Use sed replace EXPRESSION to transform file names.

which means --xform='s|path/to/||' would remove path/to/ from the path;
and

--exclude=PATTERN
      Exclude files matching PATTERN, a glob(3)-style wildcard pattern.

so you could run:

tar -zcvf /path/to/compressed/"$(date +%d-%m-%Y-%T)"-testdir.tar.gz \
--transform='s|^path/to/||' /path/to/compress \
--exclude='cache' --exclude='logs' --exclude='bootstrap.php.cache'

Note there's no leading / in the expression used with xform. A more generic approach:

--xform='s|^([^/]*/){2}||x'

That would strip the first two elements of the path (replace 2 with another number - as needed).

  • What would be the output of this one? The same but using another approach? If so valid too thanks – ReynierPM Mar 1 '15 at 21:01
  • @ReynierPM - the output is as per your question. The difference when using --xform is that you don't have to cd to the parent directory & use relative paths. Only available with gnu tar afaik. – don_crissti Mar 1 '15 at 21:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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