remix logo

Hacker Remix

The useful use of cat

93 points by LorenDB 4 days ago | 105 comments

Arcuru 3 days ago

Using `cat file.txt | ...` has always felt more natural to me, so I still use it.

If I need to build a long command I've been using the excellent `up` tool to do it, e.g. `cat file.txt | up`

https://github.com/akavel/up

latexr 3 days ago

> Using `cat file.txt | ...` has always felt more natural to me

Use whatever you prefer¹, but if what you care for is the logic of reading left to right, you can do so without `cat` by doing instead `< file.txt | ...`

¹ It’s absurd this needs to be spelled out, but here we are.

knighthack 3 days ago

I don't care about fancy '<' syntaxes.

I want to type 'cat'.

The visual imagery of summoning a cute cat to do my POSIX sorcery trumps all else.

latexr 3 days ago

> I want to type 'cat'.

Then do. I’m certainly not stopping you, or saying you’re wrong to do it. I offered an alternative with no judgement for the other method.

kazinator 2 days ago

Since when can you summon a real cat using the word cat? Or any word?

oneeyedpigeon 3 days ago

They're saying they find "cat" more natural than "<" which I can understand. Unless you regularly use "<", it's probably easier to remember "cat" and it's more self-documenting.

latexr 3 days ago

> They're saying they find "cat" more natural than "<" which I can understand.

I don’t think that’s what they’re saying. I think they’re making the point that going left to right with the file first is what makes sense to them, as opposed to `... < file.txt`.

oneeyedpigeon 3 days ago

You're assuming they don't know about `<file.txt ...` That may be the case, but I can still see an argument for "cat" being more natural than "<" in this context.

latexr 3 days ago

> You're assuming they don't know about `<file.txt ...`

And you’re assuming they do. It’s safe to assume at least one person reading the comment won’t know about the feature, the information is useful to more than that poster.

> but I can still see an argument for "cat" being more natural than "<" in this context.

You’re also assuming I don’t understand that sentiment. That has nothing to do with my original post. I don’t care what you use, do whatever makes you happiest. I was merely offering an alternative that would still satisfy what I perceived to be the original point (command piping left to right) to share knowledge, I was in no way criticising their method or saying they shouldn’t use it.

This is a useless conversation.

Arcuru 3 days ago

No I can't. Because I use fish shell. `cat` can also be a single character if you alias it :)

REDS1736 3 days ago

Wow that looks amazing, thanks for telling me about this!

agumonkey 3 days ago

Indeed. A good addition to fzf and bat

codesnik 3 days ago

if you prefer to use cat just to read your pipeline from left to right, you can just start your command with file redirection. It doesn't have to be at the end of the command.

  <file grep something | do something else ...
this works in bash too, but if you're using zsh, there're a couple of nice shortcuts

  <file
on it's own works as

  more file
and

  > file
  ...
  ...
  ^D
allows you to put something into the file quickly without firing up the editor. Though

  > file << end
  ...
  end
will give you nicer line editing experience.

more zsh redirection tricks here: https://zsh.sourceforge.io/Doc/Release/Redirection.html#Mult...

globular-toast 3 days ago

If I saw

    <file grep ...
It would give me pause. If I saw

    cat file | grep ...
I would understand it instantly, as would any other Unix user. Therefore the latter is better code.

MathMonkeyMan 3 days ago

My coworker said the same thing. But now that you know, will it give you pause?

Shell has tricky and arcane corners that are best to avoid, but you still do better to know about them, lest they bite you (shellcheck helps).

I don't think that "I/O redirection can precede the command name" is particularly tricky or arcane.

What bothers me is that it doesn't work with loops:

    <input.txt while read -r line; do thing; done # error

    while read -r line; do thing; done <input.txt # fine
The shell's grammar is quite a thing.

cellularmitosis 3 days ago

“Subsetting” a language is a useful practice. Consider the set of language features someone has to know in order to understand your code. If you can make that set smaller (without unreasonably sacrificing functionality), you lower the barrier to entry. More people can read your code.

The typical retort I hear is “but it’s just this one feature, how hard is it to learn just one feature?” But you’re only considering your favorite feature. To the casual code reader, it isn’t just that one feature, it’s everyone else’s favorite obscure feature as well.

Using cat makes your code readable to a wider audience. Using cat has real upside with no downside. Forcing your readers to learn more shell syntax has real downside with no practical upside.

MathMonkeyMan 3 days ago

You make good points. The only part I disagree with is "forcing your readers to learn more shell syntax." Who am I to say what the reader does or doesn't know about the shell? I don't even know what I don't know about the shell. The language is a minefield. I always have to look up the rules for how prefix/suffix substitution works, or the finer points of heredocs, or just when exactly something should be quoted, or the precedence of boolean operators, or the difference between "[" and "test", or ...

Yes, let's be considerate and not use these features. But then we must agree on the specifics of the subset. If we're going to do that, then let's just learn the language proper instead. Or, avoid shell scripts entirely.

Maybe there's an analogy with writing prose. I _could_ use rare words and uncommon syntax, but the modern style is a better approach. Is "abstruse" a rare word? Will a reader be frustrated to necessarily learn about split infinitives? What about I/O redirection at the beginning of a command?

Brian_K_White 2 days ago

Readability is a concern, but it is only one concern among a bag of conflicting concerns, and it is meaningless to make decsions based on it before deciding the priority of all concerns.

Sometimes the readability is the most important feature and all other concerns can be compromised or sacrificed to readability.

But for me, usually not. As far as I'm concerned that is limited to training materials and showing your work in math exams. The rest of the time it's merely a goal after all other goals, ie you don't want things to be actually obfuscated, all else being equal.

latexr 3 days ago

By that argument, no one would ever learn anything.

Everything in programming is new to someone at some point. There are useful features few people know about, and you get them to be widespread and familiar by using and talking about them.

Just because you only ever learned about `for` loops doesn’t mean you shouldn’t understand and use `map`.

CBLT 3 days ago

I don't feel <file is obscure. I've seen shell in that style from coworkers and from open source. Your value judgement against it might just be your experience, rather than something universal.

g-b-r 3 days ago

For sure many people don't know what it does

Furthermore, a little memory lapse or typo, and, oops! >byebyefile

strunz 3 days ago

It's definitely more obscure than cat, and even those familiar might be confused with it at the beginning of the line

zahlman 3 days ago

`<file` at the start might not be idiomatic, but when I see it I think it makes perfect sense. It puts the pipeline "in order", starting with redirection from the input (and presumably ending with redirection to the output, if not stdout).

HappMacDonald 3 days ago

I usually interpret `command <fileA >fileB` as meaning "shove fileA into this command, and shove output into fileB". The "arrows" make visual sense this way.

`<fileA command` OTOH at least visually gives off the impression that it's sending the command's output to the left (changing the prompt, perhaps?)

oneeyedpigeon 3 days ago

If only we could do `fileA> command >fileb` for the ultimate readability...

chgs 3 days ago

Or you could just use cat

mingus88 3 days ago

Coward, use `tail -c +0` like the rest of us useless command cowboys

seba_dos1 2 days ago

It's actually very useful when used with wildcards/multiple arguments!

kazinator 2 days ago

  cat file|grep x
  <file grep x
  grep x file
The two alternatives are several keystrokes less and remove a useless process.

gorgoiler 3 days ago

It’s shell specific though, just like using FOO=bar cmd prefixing to make environment changes. Better to use env(1) and keep everything rooted in Unix processes rather than shell syntax, imho.

  # bashisms
  <file tr z-o m-g | …
  FOO=bar python3 …

  # processes
  cat file | tr z-o m-g | …
  env FOO=bar python3 …

shiomiru 3 days ago

File redirection is specified in POSIX:

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V...

So is FOO=bar cmd.

(I guess it is shell-specific if you include csh in the game, but then what isn't...)

MathMonkeyMan 3 days ago

Both of the features that you mention are specified in POSIX, which means that bash, ksh, zsh, sh, ash, dash, etc. implement them.

I find myself googling "OpenGroup shell command language" pretty often to check this sort of thing.

kelnos 3 days ago

People who get up in arms about "useless" uses of cat need to chill out. I read my pipelines left to right. Using a '<' redirection to pull the data in after the command means I have to swap my reading direction back and forth, and why bother with that? I have better things to do with my brain energy.

bloppe 3 days ago

As others have mentioned, you can put `<` anywhere in the command, including at the very beginning. But, I agree that getting up in arms about this is really dumb.

sim7c00 3 days ago

cat all the things. i cat | grep and im not ashamed of it! cat | less - why not.? its not going to melt my pc more or less if i cat | more | less...

Lockal 3 days ago

You may miss some optimizations for cat | tail. And you can't --follow a cat, obviously!

moffkalast 3 days ago

It's the cat's meow!