4 ms·
The problem is that according to this argument `cat` should never be used for the thing it was designed for, because if you use it with more than one argument,
by crdrost 2y ago
The problem is that according to this argument `cat` should never be used for the thing it was designed for, because if you use it with more than one argument, it would give most Unix users pause, but if you saw it with only one argument they would understand it instantly.
The whole point of the "never use cat" Unix advice is a war between instrumentalism and design purism. Should things be known mostly for what they're useful for, or mostly for what they were made to do? If you understand this, then the war is not soluble but you can at least phrase a third position that will reconcile both sides. If you don't understand this, then the war is over an issue that doesn't even exist.
Hot take: `<file> | abc` and `abc | <file>` should both make sense because a file should be understood by default as a command that reads from and writes to a particular destination, and the shell should take it seriously that `abc | <file>` needs to be easily undoable if the file wasn't chmodded +x appropriately.
- deleted 2y ago[deleted]
- makapuf 2y agoWhat if you want to grep a bash script file?
- pastage 2y agoCan you explain what fou mean by <file> | abc? I have no clue what that would mean. Further what does undoable mean in a shell context?
- oktoberpaard 2y agoSo `abc | <file>` would write the stdout of `abc` to the file? Meaning that if you forgot to mark your script as executable, you’ve now lost all your work? I think `abc > <file>` works perfectly fine and pipes don’t need to substitute this behavior.
- crdrost 2y agoThat's the point is that it's up to the shell to make sure that you don't use your work if you do the wrong thing. Could be as simple as prompting you to make sure -- "Overwrite <filename>? [yn]: " -- or could be something where the old inode is still available under some magic path for a few more commands, or could be that you use special syntax for the command, like "@<path>" is the stdin/stdout command form for the path... or it could be something else entirely, really. For an instance where there are thousands of bash scripts out there that work around a case where `abc >file` does not work, consider the times when you want to write to a file which you don't have write permissions to, with sudo. my favorite way to do this is with `tee` but I have also seen others: but `>file` is not one of them! Because it's emphatically not part of the algebra of the rest of the shell; the rest of the shell is written in pipes, this one command says "I'm going to make your pipeline terminate, this step will be un-pipeable." For another example where the algebra doesn't consistently handle the whole system, consider that in a normal language you would consider writing a function which returns a value and also prints debug logs to the process's stdout. Bash can't do this on its own, you have to figure out which /dev/tty is attached to the process and then write your debug log to that TTY, and then your script probably fails in interesting ways when it itself is redirected to a file and there is no TTY that it is attached to anymore...
- oktoberpaard 2y ago> That's the point is that it's up to the shell to make sure that you don't use your work if you do the wrong thing. And how do you envision this would work inside a non-interactive Bash script? A shell option or environment variable that removes the confirmation step? With alternative syntax this would indeed work, because then it’s explicit. > this one command says "I'm going to make your pipeline terminate, this step will be un-pipeable." And your method would work like tee and not only write to the file, but also pass it on to the next step in the pipe? If not, the pipe still terminates at that point.
- globular-toast 2y agoIt is the thing it was designed for: CAT(1) concatenate [one or more] files and print on the standard output A list of length one is still a list. It's best to write code that can handle lists of any size, not to write special cases that handle a fixed number of primitives. You can swap `cat` for `zcat`, for example, and things still work in just the same way. This would be very awkward to do with input redirection. Maybe using `cat` like this appeals to people with more of a functional programming exposure. If we were going to completely change the shell behaviour I think `file > grep` makes more sense than `file | grep`.