Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TAR with --to-command

Tags:

tar

I'd like to calculate MD5 for all files in a tar archive. I tried tar with --to-command.
tar -xf abc.tar --to-command='md5sum'
it outputs like below.
cb6bf052c851c1c30801ef27c9af1968 -
f509549ab4eeaa84774a4af0231cccae -

Then I want to replace '-' with file name.
tar -xf abc.tar --to-command='md5sum | sed "s#-#$TAR_FILENAME#"'
it reports error.
md5sum: |: No such file or directory md5sum: sed: No such file or directory md5sum: s#-#./bin/busybox#: No such file or directory tar: 23255: Child returned status 1

like image 671
Zukang Avatar asked Aug 31 '16 07:08

Zukang


People also ask

What does the command tar XVZF * .tar do?

gz using option -xvzf : This command extracts files from tar archived file. tar.

What is Z option in tar?

Use the -z option to extract a tar.gz file: tar xzf <archive name>.tar.gz. The command extracts the contents in the current directory.

What is tar in command line?

The tar command stands for tape achieve, which is the most commonly used tape drive backup command used by the Linux/Unix system. It allows for you to quickly access a collection of files and placed them into a highly compressed archive file commonly called tarball, or tar, gzip, and bzip in Linux.


2 Answers

You don't have a shell so this won't work (you also might see that the | gets to md5sum as an argument). one way could be to invoke the shell yourself, but there is some hassle with nested quotes:

tar xf some.tar --to-command 'sh -c "md5sum | sed \"s|-|\$TAR_FILENAME|\""'
like image 157
Patrick J. S. Avatar answered Oct 15 '22 19:10

Patrick J. S.


At first, it's better to avoid using sed, not only because it's slow, but because $TAR_FILENAME can contain magic chars to be interpreted by sed (you already noticed that, having to use # instead of / for substitution command, didnt you?). Use deadproof solution, like head, followed by echoing actual filename.

Then, as Patrick mentions in his answer, you can't use complex commands without having them wrapped with shell, but for convenience I suggest to use built-it shell escapement ability, for bash it's printf '%q' "something", so the final command be like:

tar xf some.tar \
    --to-command="sh -c $(printf '%q' 'md5sum | head -c 34 && printf "%s\n" "$TAR_FILENAME"')"

"34" is number of bytes before file name in md5sum output format; && instead of ; to allow md5sum's error code (if any) reach tar; printf instead of echo used because filenames with leading "-" may be interpreted by echo as options.

like image 43
Alex Offshore Avatar answered Oct 15 '22 19:10

Alex Offshore