Just noticed the comment about MacOS, and while I think the solution from @akira (and pv) is much neater I thought I'd chase a hunch and a quick playaround in my MacOS box with tar and sending it a SIGINFO signal. Funnily enough, it worked :) if you're on a BSD-like system, this should work, but on a Linux box, you might need to send a SIGUSR1, and/or tar
might not work the same way.
The down side is that it will only provide you with an output (on stdout) showing you how far through the current file it is since I'm guessing it has no idea about how big the data stream it's getting is.
So yes, an alternative approach would be to fire up tar and periodically send it SIGINFOs anytime you want to know how far it's gotten. How to do this?
The ad-hoc, manual approach
If you want to be able to check status on an ad-hoc basis, you can hit control-T
(as Brian Swift mentioned) in the relevant window which will send the SIGINFO signal across. One issue with that is it will send it to your entire chain I believe, so if you are doing:
% tar cvf - folder-with-big-files | bzip2 -c > big-files.tar.bz2
You will also see bzip2 report it's status along with tar:
a folder-with-big-files/big-file.imgload 0.79 cmd: bzip2 13325 running
14 0.27u 1.02s
adding folder-with-big-files/big-file.imgload (17760256 / 32311520)
This works nicely if you just want to check if that tar
you're running is stuck, or just slow. You probably don't need to worry too much about formatting issues in this case, since it's only a quick check..
The sort of automated approach
If you know it's going to take a while, but want something like a progress indicator, an alternative would be to fire off your tar process and in another terminal work out it's PID and then throw it into a script that just repeatedly sends a signal over. For example, if you have the following scriptlet (and invoke it as say script.sh PID-to-signal interval-to-signal-at
):
#!/bin/sh
PID=$1
INTERVAL=$2
SIGNAL=29 # excuse the voodoo, bash gets the translation of SIGINFO,
# sh won't..
kill -0 $PID # invoke a quick check to see if the PID is present AND that
# you can access it..
echo "this process is $$, sending signal $SIGNAL to $PID every $INTERVAL s"
while [ $? -eq 0 ]; do
sleep $INTERVAL;
kill -$SIGNAL $PID; # The kill signalling must be the last statement
# or else the $? conditional test won't work
done
echo "PID $PID no longer accessible, tar finished?"
If you invoke it this way, since you're targeting only tar
you'll get an output more like this
a folder-with-big-files/tinyfile.1
a folder-with-big-files/tinyfile.2
a folder-with-big-files/tinyfile.3
a folder-with-big-files/bigfile.1
adding folder-with-big-files/bigfile.1 (124612 / 94377241)
adding folder-with-big-files/bigfile.1 (723612 / 94377241)
...
which I admit, is kinda pretty.
Last but not least - my scripting is kinda rusty, so if anyone wants to go in and clean up/fix/improve the code, go for your life :)
6Nice, a one liner. Can you explain it? Or does it just magically work somehow? – Kissaki – 2014-10-04T18:02:48.240
Can you write command to extract tar file like above? – Krzysztof Szewczyk – 2014-11-26T13:47:54.257
2Ok, I have it
pv $FILE.tgz | tar xzf - -C $DEST_DIR
– Krzysztof Szewczyk – 2014-11-28T07:57:07.1101For OS X, I needed to use the square bracket form for arithmetic expansion, which made:
tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gz
Without this change, I was getting-bash: syntax error near unexpected token ')'
– Dean Becker – 2015-03-19T11:18:56.290Any idea how to make this work with
pixz
? For me, it works withgzip
,pigz
andxz
, but not withpixz
,pxz
or when specifying multiple cores to xz (xz -T<num>
) – joelostblom – 2016-02-03T20:30:04.777I've wrapped this oneliner in a bash function here: https://github.com/equant/my_bash_tools/blob/master/tarp.bash
– equant – 2017-09-29T20:59:00.887thanks! I used it for backing up my home dir https://gist.github.com/timabell/68d112d66623d9a4a3643c86a93debee
– Tim Abell – 2018-03-15T10:34:23.063Hello, how to do it for combining multiple directory/files into a one zip file? – Sisir – 2018-07-12T06:20:59.537
1Note that the progress doesn't show until the du command finishes which could take a while depending on the size, complexity, and fragmentation of the directory. – Rooster242 – 2019-01-10T20:11:48.960
1I'm a bit late to the party, but I was wondering why this answer suggests the use of the -P option on tar. That seems like bad advice, given that the OP didn't mention a need for absolute paths in the tarball (and having them can cause real headaches when it comes time to extract the archive). – Brian A. Henning – 2019-02-15T16:25:40.230
@KrzysztofSzewczyk this does not work with a tar.xz archive. i tried variants of
pv archive.tar.xz | tar xf - -C ~/location
,pv archive.tar.xz | tar xf -J -C ~/location
,pv archive.tar.xz | tar xf --C ~/location
,pv archive.tar.xz | tar xf -JC ~/location
, ... but none seem to work. without pv it's :tar xf archive.tar.xz -C ~/location
– tatsu – 2019-03-08T10:13:29.0501
okay I figured it out thanks to this : https://stackoverflow.com/a/19372542/4770754 , it's :
– tatsu – 2019-03-08T10:19:58.527pv archive.tar.xz | tar xp -J -C ~/location
For those who only want to
tar
without compression on macOS:tar -c folder-with-big-files | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] > folder-with-big-files.tar
. – Bugs Bunny – 2019-09-02T20:00:20.803what in the world is 'pv'? doesnt seem to exist on Mac OS X – qodeninja – 2019-09-25T02:47:41.237
Might I suggest using
cut
instead ofawk
for this? Likecut -f1
instead ofawk '{print $1}'
? – Tripp Kinetics – 2019-10-09T15:57:07.987The reason why I suggest is that it's a little less fault-prone, and is a much lighter command. – Tripp Kinetics – 2019-10-09T15:59:53.193
2On OSX, du does not take -b argument, needed to fallback to : $((du -sk /folder-with | awk '{print $1}') * 1024)) – ıɾuǝʞ – 2013-11-29T10:14:25.840