TermKit
TermKit copied to clipboard
Cat should not be cat
You're using "cat" as a way to display the contents of one file. This would qualify for a Useless Use Of Cat everywhere on the internet. Read me well there:
*** cat is for concatenating ***
It should really be more or less (or a non-paging equivalent, whatever but cat).
"open" is already taken as a shell built-in, that opens it externally. Cat makes sense to a beginner, who is used to using cat to view files. "view" could be an alias for cat... but removing that functionality makes little sense.
However, I do agree that running cat on two files (as in, how concatenate WORKS) gives a humorous error.
Multiple input files not supported yet.
Well I sure was not advocating for open, but rather more or less which are ultimately meant to display the content of (text) files.
I also consider letting noobs believe cat is the way to go (e.g. by advertising it used in that way in the documentation) isn't a good thing. It should still work, but there should be another way of getting it done that does not involve cat.
Romain: I think that ship has sailed. The entire internet thinks cat is for displaying files. But thanks for teaching me something :P
@boxed: your comment on how "the entire internet thinks cat is for displaying files" actually got me all like "OMG, SOMEONE IS WRONG ON THE INTERNETS" in my mind.
If you info coreutils 'cat invocation'
you'll see
cat' copies each FILE (
-' means standard input), or standard input if none are given, to standard output.
Where FILE can be singular.
So "viewing" a single file with cat on standard output is a completely valid and common use of this command irrelevant of experience.
Also more
or less
are not, strictly speaking, simply "meant to display the content of (text) files". If you man more
or man less
you'll see that they exist primarily as a "filter for paging through text one screenful at a time". So if you don't need paging, you'd just cat
the file...
So if the aim was to be as close as possible to the current commands while adding image support all of the following should work...
cat image.png
cat image.png | less
less image.png
cat image1.png image2.png > image3.png
The fact is it is usually useless to "display" (text) files for user viewing without some paging logic (which basically more/less provide), whereas cat is usually (properly) used to pipe (or otherwise redirect) the concatenation of several files to somewhere else. From that point of view, the semantics of "I want to read/see the contents of the file" is better conveyed with more/less than it is with cat.
view is also a nice way of putting it, since it appears to be a pretty standard alias for vi (though only the fact the name ties to the semantics appeals to me, the fact it aliases to vi usually is not relevant).
@RomainMuller
Some interesting thoughts but I respectfully disagree.
cat is only a historical name, not the definition of the command. any pragmatic use of a tool that works is "proper".
cat's own manpage states the purpose of the command is to take one or more files, or standard input, and _print to standard output. concatenation happens to be a necessary feature for the multiple files use case, but _doesn't even occur for the completely valid single file or standard input use cases.
Wikipedia states "cat...is a standard Unix program used to concatenate and _display files_".
The Jargon file states "[techspeak] To spew an entire file to the screen or some other output sink without pause (syn. blast)." and "Among Unix haters, cat(1) is considered the canonical example of bad user-interface design, because of its woefully unobvious name. It is far more often used to blast a file to standard output than to concatenate two files. The name cat for the former operation is just as unintuitive as, say, LISP's cdr."
If your argument is only that cat is a bad name then I agree, but it is the name we already have for an established command in the unix world for displaying files to standard output.
As to if TermKit should follow the established unix convention, or "improve" on the "semantics" of the commands, I'm not sure about that.
Cheers
Disclaimer: the following two paragraphs might look a lot like troll food or flame wars gears. Reader is advised to take it with a pinch of salt.
As one knows, Wikipedia is always right about anything. I will obviously not go there and create a page about myself that states I'm the master of the known universe. Never, ever. On the other hand, the Jargon file, as its name suggest, is about Jargon, and not command documentation. Also, because at some point people mostly used dynamite to blast bank walls open, doesn't mean that Nobel intended it to rob banks.
By the way, Wikipedia also knows about the Useless Use of Cat also, and does not forget to trace its roots back to 4chan, where all computer stuff were or will be discussed at some point.
Note: The disclaimer stops applying here. Yeah right there.
Eventually, @superstructor got the core stuff: it vastly depends on what the intent of TermKit is. I phrased the issue in a willingly sharp manner, based on the predicate TermKit tries to get the borking, bad UI out of the terminal world. In my opinion it encompasses stopping the bleed of badly named, widely misused, actually only marginally useful commands.
@RomainMuller, let me phrase this differently. If one wishes to dump a single file to standard output without any paging, concatenation or unnecessary fluff, what is one command other than cat to easily do so ?
Well. Trick question... I can't think of anything else than abusing cat or tee to achieve this, but now, let me ask the next question: why on earth would I be willing to dump that 12MB log file to STDOUT without any paging, concatenation or unnecessary fluff? My believe is that it is useless to do this unless you at least have pagination.
If the answer to this is "So you can pipe it to something else", then use I/O redirection and save a heavy process spawn, and make the pipe receiver's STDIN fseek-able.
can't think of anything else than abusing cat or tee to achieve this
agreed. cat file
or <file tee
both work.
why on earth would I be willing to dump that 12MB log file to STDOUT without any paging, concatenation or unnecessary fluff?
agreed you would want pagination or tail
for such a large amount of text. but what if the file, or image in termkits case, is only one screen or less lines ?
If the answer to this is "So you can pipe it to something else", then use I/O redirection and save a heavy process spawn
agreed, although with fast modern machines many still use cat either because they don't know about I/O redirection or they don't care.
I think you have made a valid point that cases where you want to display a file, and not have pagination, are a marginal use case. I still maintain that however marginal it is a valid use of cat.
So I guess the question is then should TermKit support a marginal use case ? Maybe not. But then what command can dump an image to std ouput? I like my vim too much to personally like the view
suggestion, although it makes sense "semantically".
Granted I agree on all your points. View this issue as an open poll about the design intent of @unconed :)
I propose that the current variant of cat
is entirely unnecessary. What I would expect cat
to do is taking the contents of a file, and blindly writing it out with a content type of text/plain. This lets me inspect files on a really low level, even when I am in a "high-level" shell like TermKit. This is what I use cat
for today in bash
, it is not a use-case I have made up for the sake of argument.
In order to talk about files with their (likely) correct content-type, I propose referencing/executing the file directly, as in ./image.png
. There is no directly analogous functionality in bash
, but this is only because bash
doesn't have formatters like TermKit has. In other words: bash
can only make sense of a stream of bytes. TermKit, on the other hand, can make sense of files directly.
Of course, there might be other solutions I would be just as happy about. I just wanted to add my voice to those that expect cat
to behave like cat
:)
maghoff: Actually, what I've been playing with goes in the opposite direction.
The fact that the output of cat is shown in rich view should not be considered an aspect of cat. It is an aspect of the display layer. The reason to format the output using the richest display possible by default, is to make sure the user always gets the most useful, most understandable representation possible. As opposed to today, where we sometimes 'barf' binary data into the shell, possibly corrupting the prompt in the process.
One way of solving your question is to allow you to toggle the output back and forth to raw in the UI. But, this introduces a lot of complexity, and means you're involving additional interaction, keyboard or mouse, to get what you want.
Unix already solves this problem. We pipe things through formatters to get it to look the way we want. e.g. 'od' to turn binary into hex. Hence, the TermKit solution is to provide tiny utilities like 'hex' or 'raw' which you can pipe things through, and whose only purpose is to alter the type hint on the stream. The desired display will come out of the display layer. I think this is much more natural.
Cat is a file concatenation tool. In the typed world of TermKit, it seems to make sense to continue doing that. So it will concatenate the streams, but also, run some logic to determine the content type of the output. If both streams are "text/plain; charset=utf-8", then that's what the output will be. If you concatenate two different text based formats, e.g. JSON and Python, the specific types will be resolved into the common 'text/plain'. This only applies to formats whose syntax tolerates concatenation. So JavaScript + JavaScript is still JavaScript, but e.g. JSON+JSON will still come out as "plain text", as JSON objects cannot be concatenated.
For the use case where you want to merge e.g. two JSON objects, there would be a different command ('merge' ?).
I should also add that the formatters are smart enough to realize when binary data is coming as text (e.g. as the output of a unix tool) and will transparently act like 'hex' as a fallback.
unconed: Sounds like a good start!
But I am curious; how would it decide what to do with which types? For example, while JSON+JSON in general doesn't make any sense, it is appropriate if you are working with JSONRPC, which deals in streams of JSON objects. So it might make sense to have some user-defined aspect in all of this, to allow specific concatenations in specific situations. This probably extends to tools other than cat
as well, in some manner.
Alternatively, one could add type annotations along the way (such as cat a.json b.json | reinterpret-as text/json-stream | ./program_that_deals_with_jsonstream
), but that's not particularly neat :)
So, what I am wondering is; What are your thoughts on this?
I do agree with unconed that visual data should always be displayed in the most representation available at the moment. But what about rich data that is not visual, let's say an mp3 file? Cat'ing an mp3 right now, shows you the content-type and length, nothing particularly useful. Should be more like some ID3 tags, or something else. How could an audio file (also video files, for that matter) be represented transparently in TermKit? Should there be a command like play? Or should get do that (coz right now, it doesn't)?