12th Feb 2017
Tar's Force-Local Switch
or Why Can't
tar Cope With Colons?
You're probably here because of one of these two error messages:
tar: Cannot connect to hostname: resolve failed tar: hostname:filename: Cannot open: Input/output error
Don't worry, it's easily fixed, with a little bit of understanding of Unix history.
Back in the days of yore...
Back in the old days of Unix, there was a command called "
rsh". If you were around in those days, you will know
it; if you were not, well, it was similar to "
ssh", but without any of the good bits. Basically, you could set up a
$HOME/.rhosts, or a global file named
/etc/hosts.equiv, and any named host (or user:host combination)
would be allowed to log in to your account. They were simpler, more trusting times.
If you want an idea of how old and bad it is note the "BUGS" section on the FreeBSD man page: "The rlogin utility will be replaced by telnet(1) in the near future." So yeah, pretty old. And bad.
Why is this relevant today?
Well, certain implementations of "
tar" were able to use this facility. You could extract an archive from a remote
machine, for example:
john@saturn$ tar -xvf venus:misc/myfiles.tar tar: blocksize = 15 x myfiles, 0 bytes, 0 tape blocks x myfiles/b.txt, 29 bytes, 1 tape blocks x myfiles/e.txt, 29 bytes, 1 tape blocks x myfiles/d.txt, 29 bytes, 1 tape blocks x myfiles/c.txt, 29 bytes, 1 tape blocks x myfiles/f.txt, 29 bytes, 1 tape blocks x myfiles/a.txt, 29 bytes, 1 tape blocks john@saturn$
I must admit, I've not yet managed to find a combination of machines with this awful combination, but it must look 95% like the above.
Why do I care?
The main reason that you are likely to care, is if you are trying to deal with a
tar file with a colon in its name:
$ tar cf my:files.tar * tar: Cannot connect to my: resolve failed $
Or even (with a massive delay as it tries to connect to Google):
$ tar cf google.com:files.tar * ssh: connect to host google.com port 22: Network is unreachable tar: google.com\:files.tar: Cannot open: Input/output error tar: Error is not recoverable: exiting now $
tar is trying to do, is connect to a server called "
my" and create an archive called "
files.tar". In the second case, it's trying to connect to
google.com and create an archive there. That is quite unlikely to succeed, unless you happen to have an
rlogin account on
google.com (hint: Nobody has one of those!)
tar's ability to interpret a "
hostname:filename" argument as a host/file pair, is its "
--force-local" switch, which disables this behaviour.
$ tar --force-local -cf google.com:files.tar *
tar not to try to be so damned clever, and just take the filename it was given, without trying to convert it into a hostname:filename pair.
Even More Gotchas
Before you think you're out of the woods already; a lot of people have bad habits with
tar syntax, even though they might not realise it.
Most people will either use "
tar cvf foo.tar file1 file2" or "
tar -cvf foo.tar file1 file2".
tar does nobody any favours by accepting arguments either with or without the "minus". It makes
tar syntax harder to think about.
See, for example, https://xkcd.com/1168/:
So we have to think about the switches. Be very precise. You can combine single-character switches (like "
cvf") together, but
f" is really a "
-f filename" argument. So the two need to go together.
So it's worth being in the habit of using the minuses, and make sure that you keep the "
-f" next to the actual filename that you want
tar to use. For example: "
tar -cvf --force-local foo.tar file1 file2" is not right, because it will attempt to create an archive file called "
--force-local" containing the files
Invest in your career. Buy my Shell Scripting Tutorial today:
og:image credit: Unknown. Please contact me if source is known.