There I said it !
I think that providing an exit status that is not 0 when
zcat
is used with an uncompressed file is useful. Though my opinion is less strong regarding whether it should write more text after an error occurred, it’s probably more useful for a process to terminate quickly when an error occurred rather than risk a second error occurring and making troubleshooting harder.I think that trying to change any existing documented features of widely used utilities will lead to us having less useful software in the future (our time is probably better spent making new programs and new documentation): https://www.jwz.org/doc/worse-is-better.html https://en.wikipedia.org/wiki/Worse_is_better
Not improving existing software leads to stagnation.
It’s certainly a good part of why so much of linux is an awkward kludgy idiosyncratic mess to use.
Whatever the first implementation does ends up being a suicide pact by default.
Another option is to change cat to auto decompress compressed files, instead of printing gibberish.
How do you propose zcat tell the difference between an uncompressed file and a corrupted compressed file? Or are you saying if it doesn’t recognize it as compressed, just dump the source file regardless? Because that could be annoying.
Even a corrupt compressed files has a very different structure relative to plain text. “file” already has the code to detect exactly which.
Still, failing on corrupted compression instead of failing on plaintext would be an improvement.
I agree. zgrep also works for uncompressed files, so we could use e.g.
zgrep ^
instead of zcat.Thanks, didn’t know that existed
That’s basically everything I was looking for !
Yeah, it’s a pain. Leads to bad one liners:
for i in $(ls); do zcat $i || cat $i; done
Btw, don’t parse ls. Use
find |while read -r
instead.find -maxdepth 1 -name "term" -print |while read -r file do zcat "$file" 2>/dev/null || cat "$file" done
Won’t this cause cat to iterate through all files in the cwd once zcat encounters an issue, instead of just the specific file?
You are correct. This probably produces something more similar to what you’d want the original command to do, but with better safely:
find -- . -type f -regex '^\./[^/]*$' -exec sh -c -- 'for file in "${@}"; do zcat "${file}" || cat "${file}" || exit; done' sh '{}' '+'
That assumes you want to interact with files with names like
.hidden.txt.gz
though. If you don’t, and only intend to have a directory with regular files (as opposed to directories or symbolic links or other types of file), using this is much simpler and even safer, and avoids using files in a surprising order:for i in *; do zcat -- "$i" || cat -- "$i" || exit; done
Of course, the real solution is to avoid using the Shell Command Language at all, and to carefully adapt any program to your particular problem as needed: https://sipb.mit.edu/doc/safe-shell/
Yeah, i was tired and had $file there first, then saw that you wanted to cat all in directory. Still tired, but i think this works now.
Thanks !
But still we shouldn’t have to resort to this !
Also, can’t get the output through pipefor i in $(ls); do zcat $i || cat $i; done | grep mysearchterm
this appears to workfind . -type f -print0 | xargs -0 -I{} sh -c 'zcat "{}" 2>/dev/null || cat "{}"' | grep "mysearchterm"
Still, that was a speed bump that I guess everyone dealing with mass compressed log files has to figure out on the fly because zcat can’t read uncompressed files ! argg !!!for i in $(ls); do zcat $i 2>/dev/null || cat $i; done | grep mysearchterm
Well, the source code is available. Fix it if you need it that bad.
Where is it? I can’t seen to find it https://github.com/zCat?tab=repositories
It’s part of GNU Gzip, and zcat is basically just a shell script that runs
exec gzip -cd "$@"
meaning you can actually just docat /usr/bin/zcat
to get the source.
Man, I have a minor inconvenience.
installs Gentoo
Celeste. Are you here? In a future search maybe?