(unix/C) “stty: stdin isn't a terminal” when u

2019-05-31 18:29发布

问题:

We're reading a file from stdin into file_buffer, and then stepping into a method more.

As soon as we use system("stty cbreak -echo");, the output prints "stty: stdin isn't a terminal" and doesn't set our terminal to the settings we asked for.

This problem only exists when we use standard in. If we use a file argument, the program works fine -- the terminal settings get set, and there is no error message.

So, this is okay: myprogram file1.txt

But this is not: myprogram < file1.txt

Either way the contents are being read into file_buffer before being used at all. What the heck is wrong with using stty if we're taking input from stdin??

回答1:

When the standard input is a file, it isn't a terminal, so setting terminal attributes on stty's standard input won't work.

It sounds daft at first, but you will probably find that you can use either stdout or stderr as the input for stty and it will adjust the terminal. Therefore:

system("stty cbreak -echo <&2");

is likely to set the terminal characteristics. If you have a GNU version of stty, you could also use:

system("stty -F /dev/stderr cbreak -echo");

or substitute /dev/stdout or /dev/tty for /dev/stderr. You could also use any of the named devices instead of the &2 in the redirection in the first variant.



回答2:

If you use input redirection or pipes, then stdin is not a TTY.

You can use isatty to check for that.