Make tar,zip,rar play nice with named pipes?
Hello all.
I'm working on a scripting project and it would be very helpful if I could make tar, zip, and rar treat named pipes just like regular files when creating an archive. That is, it would be nice if these programs would, upon encountering a named pipe, read all of the input from it and place that input into an entry in the resulting archive named the same way as the named pipe. What I need is similar to what tar h, zip without the -y option, and rar without the -ol option do for symlinks, only I need to do that for named pipes. So, for instance, this sequence of instructions: Code:
mkdir ~/bashtest Code:
total 12 Code:
total 12 If you want the long version of the story, I'm writing a script which will reside on a web server to which I and a few others admins have SSH access. This script, when invoked, will backup a directory structure and a mysql database and output the resulting .tar.gz, tar.bz2, .zip, or .rar data directly to stdout. That way, on our respective boxen, we will be able to make a backup with something like: Code:
ssh admin@server.com ~/backup.sh > mybackup.tar.gz I'm working with limited disk space on the server, so I didn't want to duplicate the existing files and dump the MySQL data into a temporary file so that I could tar zcf - the directory. So, I had the bright idea to create a temporary directory containing a symlink to the directory to be backed up and a named pipe to which I would dump the output of mysqldump. I was thinking something like this would work: Code:
cd ~ But, I've found no way to make these archivers do what I need them to do for this to work. I tried using a symlink to a named pipe with tar h, but tar was too smart to be tricked so easily. :D Any and all help would be greatly appreciated. Thanks very much for your time. :) |
Why bot just use the normal pipe?
mysql dump | tar | gzip You may need to use '-' with tar to properly take input from stdin Here's a line I use in a program which shows some syntax that may help you: This backs up files ($i) one at a time into a dir for i in $filelist ; do (tar -cpf - "$i"| tar -f - -xvpC somedir) done Then this restores them after wards: cd somedir tar -cpf - . | tar -f - -xlUvpC Since you want compressed files you'd need to use another pipe at the end to pipe into gzip/bzip. (note that the xlUvpC is syntax for tar-1.13) Ah, I forgot, I have a line which creates compressed archives of the backup dir: cd somedir tar -cpf - . | gzip -9 > "${BACKUPS_SAVE_DIR}/backup-$(date +%m%d%Y%H%M).tar.gz" Hopefully there' something there to help you out. The -l and -U options I use for tar-1.13 have to do with preservation of file metadata. I use the old tar-1.13 exactly because of the way it handles links. They make sure that a directory which is a link doesn't get overwritten as a dir. They make tar follow the link instead of replacing it with a real directory. Later version of tar have different default beahviour and syntax for doing this. You should probably check the verison you are using very carefully as thh usage and syntax is different for each version from 1.13, 1.14, 1.15 and 1.16. 1.17 seems to have finally settled the transition in syntax. But you may need to write code which checks the version and supplies alternate syntax for each version or be sure that everyone is using the same version. Have fun... |
Quote:
And... does tar even take input from stdin when creating a tar archive? It wouldn't know what to name the entry in the resulting tar file, would it? Or would it name it "-", or is there a way to give it a specific name? If there is a way to create a named entry in the tar file which has contents taken from stdin, then I could create the tar file and then use the "r" option to add the other files to the archive. Here's a quick test of taking input from stdin when creating a tar archive: Code:
echo "to be tarred" | tar cf blah.tar - Quote:
Quote:
As for the named pipe stuff. I do have one idea... and it may sound a little bit insane, but it could work. I could study the tar file format and create a script that basically produces a tar archive containing only one file (the mysql dump) and then pipe the output of that into tar which then adds the rest of the directory structure to the archive. I'll work on that and see what I come up with. Thanks for your help. :D |
The last example does create a tar.gz from stdin. The '-' following the tar command is taking the stdin from the ouput of '.' which is equivalent to 'ls'.
I think if you play with the syntax I provided you can get tar to do what you want. Just change the last part so that it creates a tar instead of just copying the files to a new dir. Another idea is that it might be better to just use cpio instead of tar. It may be less finicky and handles long names better. I'm too busy to work it out for you, but I'm quite sure that tar will do what you want. I just provided the above syntax because it shows the proper way to handle tar with stdin. |
Quote:
Quote:
Quote:
|
The power of named pipes comes when the two scripts/programs do not directly talk to each other.
Example: Code:
### Code:
### When the second piece of code runs, the first piece finishes and the files get passed to tar. xargs - build and execute command lines from standard input man xargs |
Quote:
What I'm wanting is something like this: Code:
### Code:
### Code:
### Code:
cd ~ Thanks for your help. :) |
Fair point on the errors, I was in the directory I was testing with.
If you want to keep the contents of the pipe, you would first have to pass it to a regular file, when a tar backs up a named pipe it doesn't store the contents. This isn't what you are after (you would need to tar two files and then to recover would have to restore, then load the data into the named pipe) I guess the reason I have never tried is that the data in a named pipe is typically only used to pass information between disconnected processes and is temporary (so why back it up) |
Yeah. I was afraid of that.
At least now I know I should give up on that route and try something different. Thanks again for your help. :) |
All times are GMT -5. The time now is 03:09 PM. |