LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   [BASH] How to create *.tgz file? (https://www.linuxquestions.org/questions/programming-9/%5Bbash%5D-how-to-create-%2A-tgz-file-4175455658/)

Ivano 03-26-2013 09:43 AM

[BASH] How to create *.tgz file?
 
Hello!

Script to do:
For every first-level, older than 3 months directories check if it has more than 1000 files in whole structure:
* yes - for every second-level directory do *.tgz file, check if archive is buillt correctly and remove directories that are archived,
* no - do nothing with it.

Here is what I have so far. My main problems:
1. How to create archive for second-level directories?
2. How to fix problem with empty spaces in directory names?
3. How to correctly write part with checking *.tgz files and removing archived directories (now I'm getting errors: ls: you don't have permission to /root/dir/dir: There is no such file or directory)?

Code:

for DIR in `find /root/* -maxdepth 1 -type d -mtime +90` ; do
  if [[ ! -f "$DIR.tgz" ]] ; then
    if [[ `ls -1R $DIR | wc -l` -gt 1000 ]] ; then
      tar czf $DIR.tgz $DIR
    fi
  fi
       
  if [[ -f "$DIR.tgz" ]] ; then
    rm -rf $DIR
  fi
done


mina86 03-26-2013 10:12 AM

Unfortunately, because file names can have new line characters in them, find is highly limited command, which is hard to use right. To improve things over what you are doing now you cod do:
Code:

find /root/* -maxdepth 1 -type d -mtime +90 | while read DIR; do
    …
done

but the problem with new line characters remains.

Second of all, always quote your variables. It's not always required, but if you are unsure, quote it.

Furthermore, $(…) is preferred over backtics. And lastly, you should clean up .tgz file if tar command fails. Lastly, tar's return code can be used to determine whether you need to remove the directory.

An as for counting number of files inside of a directory, find works better than ls -lR.

Code:

if ! [ -f "$DIR.tgz" ] &&
  [ "$(find "$DIR" -type f -printf \\n | wc -l)" -gt 1000 ]; then
    if tar czf "$DIR.tgz" "$DIR"; then
        rm -r "$DIR"
    else
        rm -f "$DIR.tgz"
    fi
fi

To solve problem with new lines in directory names pointed out at the beginning, the easiest way is to create another command for dealing with a directories, eg.:

blah.sh:
Code:

find /root/* -maxdepth 1 -type d -mtime +90 -exec sh blah-helper.sh {} +
blah-helper.sh:
Code:

for DIR; do
    …
done

If you don't have GNU find, replace “+” at the end of the find with “\;”.

Ivano 04-24-2013 05:00 PM

I'm sorry for no response but I had problems with my health.

I did changes and code looks like this:

Code:

find /root/ -maxdepth 1 -type d -mtime +90 | while read DIR ; do

if ! [[ -f "$DIR.tgz" ]] &&
    [[ "$(find "$DIR" -type f -printf \\n | wc -l)" -gt 1000 ]] ; then
        if tar czf "$DIR.tgz" "$DIR" ; then
            rm -r "$DIR"
        else
            rm -f "$DIR.tgz"
        fi
fi

done

Everything works fine but I have one questions. We have structure of folders like this:
Folder 1
* Subfolder 1
* Subfolder 2
Folder 2
* Subfolder 1
* Subfolder 2
Script checks if there is 1000 files in Folder 1, Folder 2 and compress it. My question: can it do same thing but compress only Subfolder 1 and Subfolder 2 when there is 1000 files in whole Folder 1? I tried do to something but everything I do fails.


All times are GMT -5. The time now is 11:28 AM.