Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

10.6: Create a new Service to 'tar' directories or files UNIX
Snow Leopard only hintWhen I need a container of files, or of a directory that is already compressed (i.e. jpg images), there is no need to 'compress' into a zip file, so the following OS X Service will replicate the Compress 'right-click' with tar:
  1. Open Automator and select Service from the main screen.
  2. Set the 'Service Receives Selected' pop-up menu to Files or Folders, and set the 'in' pop-up to Finder.
  3. Drag Utilities » Run Shell Script into the workflow area.
  4. Set the 'Pass input' pop-up to as arguments.
  5. Delete all of the sample code, and replace with this:
    Tarfile="$1.tar"
    count=1
    cd "${@%/*}"
    if [ $# -eq 1 ]; then 
      while [ -e "$Tarfile" ]
      do
        let count++
        Tarfile="$1 $count.tar"
      done
    else 
      Tarfile="Archive.tar"
      while [ -e "$Tarfile" ]
      do
        let count++
        Tarfile="Archive $count.tar"
      done
    fi
    /usr/bin/tar -chf "$Tarfile" "${@##*/}"
  6. Select File » Save and name your new Service (Package into Tar or whatever).
  7. Quit Automator and try your Service in the Finder with a selection of files.
[robg adds: This worked as described for me.]
    •    
  • Currently 2.94 / 5
  You rated: 5 / 5 (18 votes cast)
 
[6,007 views]  

10.6: Create a new Service to 'tar' directories or files | 5 comments | Create New Account
Click here to return to the '10.6: Create a new Service to 'tar' directories or files' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
.tar.gz
Authored by: pepijndevos on Apr 11, '10 04:43:22AM

Would it be possible to change this to .tar.gz by modifying the last command with the correct parameters?



[ Reply to This | # ]
.tar.gz
Authored by: FiXato on Jan 06, '12 04:08:38PM

Yes, you could add the z parameter to enable gzip compression. I Would suggest adding all the extensions too though.
Have a look at the other comment I made for my versions of the script: a revised .tar, a .tgz (tar.gz) and .tbz (tar.bz2) version



[ Reply to This | # ]
10.6: Create a new Service to 'tar' directories or files
Authored by: david-bo on Apr 12, '10 03:23:11AM

Or you could use zip -0 to set compression level to zero.



[ Reply to This | # ]
10.6: Create a new Service to 'tar' directories or files
Authored by: FiXato on Jan 06, '12 04:04:28PM

Very nice services script! It was a useful start for me!

I would recommend changing the 'h' argument to 'H' though. With 'h', you could end up trying to tar your entire harddisk if a folder contains a symlink to the root of your harddisk.
Lowercase 'h' traverses all symlinks encountered and includes the actual files in the archive.
Capital 'H' will only follow the symlink passed on the commandline, in other words: if the folder you try to archive is actually a symlink. It will retain the original symbolic links as links though.
(I discovered this problem when I tried to archive an .app that basically was a Wine wrapper. Since Wine usually contains symlinks to your homedir, it tried archiving more than I intended).

I also added 2 environment variables to my version that should prevent archiving of Mac Resource Fork files, such as .DS_Store.
COPYFILE_DISABLE=true is the current env var for it, while COPY_EXTENDED_ATTRIBUTES_DISABLE=true is a legacy env var that used to do the same thing. Included both for portability.

I also added automatic timestamping, because it helps keeping track of backups. Since the timestamp makes it rather unique, I guess the whole $count part of the script could've been removed, but I've kept it for safety anyway.

First my version of the TAR script:

export COPYFILE_DISABLE=true
export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
Tarfile="$1-$(date +%Y%m%d_%H%M%S).tar"
count=1
cd "${@%/*}"
if [ $# -eq 1 ]; then 
  while [ -e "$Tarfile" ]
  do
    let count++
    Tarfile="$1-$(date +%Y%m%d_%H%M%S)-$count.tar"
  done
else 
  Tarfile="Archive-$(date +%Y%m%d_%H%M%S).tar"
  while [ -e "$Tarfile" ]
  do
    let count++
    Tarfile="Archive-$(date +%Y%m%d_%H%M%S)-$count.tar"
  done
fi
/usr/bin/tar -cHf "$Tarfile" "${@##*/}"

And since another commenter asked about tar.gz, here is my TGZ version too:

export COPYFILE_DISABLE=true
export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
Tarfile="$1-$(date +%Y%m%d_%H%M%S).tgz"
count=1
cd "${@%/*}"
if [ $# -eq 1 ]; then 
  while [ -e "$Tarfile" ]
  do
    let count++
    Tarfile="$1-$(date +%Y%m%d_%H%M%S)-$count.tgz"
  done
else 
  Tarfile="Archive-$(date +%Y%m%d_%H%M%S).tgz"
  while [ -e "$Tarfile" ]
  do
    let count++
    Tarfile="Archive-$(date +%Y%m%d_%H%M%S)-$count.tgz"
  done
fi
/usr/bin/tar -cHzf "$Tarfile" "${@##*/}"

And for completeness-sake, one using bzip2 compression: the TBZ version:

export COPYFILE_DISABLE=true
export COPY_EXTENDED_ATTRIBUTES_DISABLE=true
Tarfile="$1-$(date +%Y%m%d_%H%M%S).tbz"
count=1
cd "${@%/*}"
if [ $# -eq 1 ]; then 
  while [ -e "$Tarfile" ]
  do
    let count++
    Tarfile="$1-$(date +%Y%m%d_%H%M%S)-$count.tbz"
  done
else 
  Tarfile="Archive-$(date +%Y%m%d_%H%M%S).tbz"
  while [ -e "$Tarfile" ]
  do
    let count++
    Tarfile="Archive-$(date +%Y%m%d_%H%M%S)-$count.tbz"
  done
fi
/usr/bin/tar -cHjf "$Tarfile" "${@##*/}"



[ Reply to This | # ]
10.6: Create a new Service to 'tar' directories or files
Authored by: FiXato on Jan 06, '12 06:56:34PM

Just noticed a minor flaw in the original code (and thus my versions too): If you select files that don't have a common directory, the action fails.
Probably because it `cd`s to the dir of the first file, and then tar fails because it can't find all files in that directory.

I have a version that works around this, but then you get full paths, which clearly isn't really what one wants either..
Maybe copying to a temp directory would work, but then you are kinda screwed if it concerns big files/directories.



[ Reply to This | # ]