←back to thread

587 points swills | 8 comments | | HN request time: 1.005s | source | bottom
Show context
pyuser583 ◴[] No.45688089[source]
I've used /dev/null for exactly this purpose. I have output that needs to go somewhere, and I don't want to worry about whether that somewhere can handle it.

Later on in deployment, it will go somewhere else. Somewhere that has been evaluated for being able to handle it.

In that way, /dev/null is to storage what `true` is to execution - it just works.

replies(1): >>45688260 #
CaptainOfCoit ◴[] No.45688260[source]
Bug free software is a pipe dream, but if there is anything I've never encountered any bugs with, /dev/null and true is certainly in the top 3.
replies(4): >>45688480 #>>45688959 #>>45690296 #>>45692706 #
noir_lord ◴[] No.45688480[source]
Joking aside I can’t ever remember seeing a bug in either bash or zsh, never seen either crash or segfault and anytime I’ve had weirdness it’s always turned out to be me missing something.

Both (along with a lot of the standard utilities) are a testament to what talented C programmers plus years of people beating on them in unintended ways can achieve in terms of reliability/stability.

replies(7): >>45688631 #>>45688712 #>>45689009 #>>45689182 #>>45689808 #>>45689909 #>>45692642 #
1718627440 ◴[] No.45689182[source]
Programs not outputting a final newline to stdout leave a prompt that doesn't start on column 0, and readline seams to not takes this into consideration, but still optimizes redraws and overwrites so you get an inconsistent display. This bugs seam to exist in a lot of shells and interactive programs. The program causing the issue isn't POSIX conform though.
replies(2): >>45689424 #>>45692721 #
tuetuopay ◴[] No.45692721[source]
I don't get why this is still the case on classic shells. fish properly puts the prompt on column zero, while outputting a small "line return arrow" at the end of the command to indicate it lacked one.
replies(1): >>45694958 #
1. mort96 ◴[] No.45694958[source]
It's arguably not the shell's role to protect against garbled output. Do you expect a shell to reset the TTY state after every command too in case you accidentally `cat /dev/urandom` and the terminal emulator enters a weird state due to random escape sequences?

The newline is a line terminator, a command outputting an incomplete line without a line terminator is producing garbled non-textual output. Files which contain incomplete lines without a line terminator are similarly garbled non-textual files and not very different from /dev/urandom or any other binary file.

replies(4): >>45695121 #>>45695354 #>>45698206 #>>45698404 #
2. schoen ◴[] No.45695121[source]
I understand the terminal-garbling issue and know that I should run "reset" in this case (and that it wasn't the shell's fault), but I bet a lot of users who aren't very familiar with this might feel that the shell is "in charge of" the terminal or "in charge of" the whole interaction, and so that it actually should be more proactive in making sure that the terminal is in a visible sensible, usable, understandable state as often as possible -- in this case probably whenever a program exits and a new prompt is displayed?
3. tuetuopay ◴[] No.45695354[source]
> a command outputting an incomplete line without a line terminator is producing garbled non-textual output

I would argue that no, there are many valid cases for commands to not produce a final \n in their output. The first example that come to mind is curl'ing a REST API whose body is a single line of JSON. Many of those will not bother with a final \n, and this does not qualify as "garbled output" in my book. I would even go as far as saying that a shell just printing the prompt at whatever place the cursor happens to be is a side-effect of how terminal emulation works and the fact it's just a character based terminal.

This is actually something that Warp does pretty well, with a strong integration with the shell where your command is in a dedicated text box, by the virtue of it being GUI and leveraging GUIs. (I don't use it however, I'm too much of a sucker for dense UIs).

However I do agree with your argument that it's not the role of the shell to protect you against `cat /dev/urandom` or `cat picture.png`. And fish indeed does not try.

IMHO a shell is built for humans when in interactive mode (one of the raison d'être of fish), and the lack of final \n is such an annoyance that handling this specific edge case is worth it.

4. kevin_thibedeau ◴[] No.45698206[source]
> The newline is a line terminator, a command outputting an incomplete line without a line terminator is producing garbled non-textual output.

A command could very well be manipulating the cursor on its own and intentionally not writing newlines when it wants to overwrite text such as in a progress bar.

5. wat10000 ◴[] No.45698404[source]
If you were designing a command-line interface from scratch, you'd definitely make it so that the command prompt gets displayed consistently and reliably after each command terminates, regardless of what garbage it spewed. The only reason we see anything different is because UNIX systems happened to grow that way, and everything gets crammed through an interface that was originally designed to show characters on physical paper.

With the design we actually have, the shell is the only thing in the chain that could reset the TTY state and ensure that the prompt gets displayed consistently each time, and it should. I wouldn't go so far as to say that I expect it to (my expectations for computers are not high in general) but it ought to.

replies(1): >>45699108 #
6. 1718627440 ◴[] No.45699108[source]
command-line interface != shell

Maybe that should be actually the job of the terminal emulator instead. It could happen when a new pseudo terminal is (de)allocated, which is ordered by the shell.

replies(1): >>45699255 #
7. wat10000 ◴[] No.45699255{3}[source]
> command-line interface != shell

I realize that. That's why I was talking about a hypothetical where it was designed all together, instead of evolving over the decades like we did.

In the situation we actually have, the shell is the only single entity that's in a position to actually do this. The terminal emulator doesn't know when a command completes. Of course, it doesn't have to be solved in a single entity. It would make sense to have the shell signal command completion to the terminal emulator, and let the terminal emulator do whatever it wishes with that information, which could include resetting any garbage state.

replies(1): >>45699543 #
8. 1718627440 ◴[] No.45699543{4}[source]
I don't think we really disagree.

I think that even when you would design it all today the distinction between interface and running program would still be useful, otherwise every program would need to implement it's own interface and a shell does more than just communicate interactively with the computer. It's also a task runner, program orchestrator, controls program selection and allows for automating other programs.

> It would make sense to have the shell signal command completion to the terminal emulator, and let the terminal emulator do whatever it wishes with that information, which could include resetting any garbage state.

The thing is, it kinda works this way already. I'm not that knowledged about the actual interaction, but the shell already tells my terminal what the current directory is, which programs it has invoked, so that my terminal emulator can show me this in the chrome.

Ok, so my stance is: Yes it is not the job of the shell to modify the output of some program, but it is the job of the shell to tell the terminal emulator to do that, when the user requests this. I'm positively minded, that actually someone can chime in and say "ah, that's just not the default, you can configure bash, readline, etc. to do that though." I think the thing is, that bash just assumes that programs are POSIX-compliant and POSIX specifies, that every programs outputs a newline. Actually POSIX doesn't define it as newline, it defines it as the end of line. A program that forgets LF doesn't have forgotten to advance output a newline, it has output an incomplete line in that reading.