Unix(Mac OS) 终端不支持 Ctrl+D 作为 EOF
Unix(Mac OS) terminal does not honor Ctrl+D as EOF
我遇到的问题:
当我玩 getchar()
行为时,我发现我的终端(macOS Mohave 版本 10.14.6 18G87)不支持 Ctrl+D 作为 EOF。
我是怎么遇到这个问题的:
带getchar()
的代码附在下面,如果输入的字符不为空,基本上这段代码就是echo getchar(),否则,对于多个连续的空白字符,它只输出一个空白字符。
代码本身有效,但是当 运行 它在终端中时,终端不会将 Ctrl+D 视为 EOF,因此 代码永远不会终止。
我确定这是因为我错误地使用了 system ("/bin/stty raw");
和 system ("/bin/stty cooked");
,但是,我不知道如何解决它。
/* K&R C Exercise 1-9. Write a program to copy its input to its output,
* replacing each string of one or more blanks by a single blank.*/
#include <stdio.h>
#include <stdlib.h>
int main(void){
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
*
* */
system ("/bin/stty raw");
while ((ch=getchar())!= EOF){
if (ch != ' ' ){
if (prev == ' '){
putchar(prev);
putchar(ch);
}
else{
putchar(ch);
}
prev = ch;
}
else{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system ("/bin/stty cooked");
return 0;
}
我检查了 stty
,但是,它确实将 EOF
配置为 Ctrl +D
。但是,现在,如果我按 Ctrl + D
,它只会将终端从一个 window 拆分为两个。
如何才能允许 EOF
重新启用?
谢谢!
此代码适用于我的 Mac 运行 macOS Catalina 10.15。我希望它在几乎任何你可以接触到的类 Unix 系统上都能以基本相同的方式工作,包括旧版本的 macOS。它通过比较 ch
和 '[=12=]4'
来发现 control-D(八进制 4 — 在标准 C 中可写许多其他方式,包括仅 4
)键入并终止循环时。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
*
* */
system("/bin/stty raw");
while ((ch = getchar()) != EOF && ch != '[=10=]4')
{
if (ch != ' ')
{
if (prev == ' ')
{
putchar(prev);
putchar(ch);
}
else
{
putchar(ch);
}
prev = ch;
}
else
{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system("/bin/stty cooked");
return 0;
}
当然,输出显示有点奇怪——例如,键入 return 不会将光标移动到下一行。但是 ch == '[=14=]4'
的测试确实检测到何时键入 control-D。 (space 消除代码也有效。)
使用 stty cbreak
而不是 stty raw
使中断启用,但通过 control-D 的 EOF 仍然被禁用。
我遇到的问题:
当我玩 getchar()
行为时,我发现我的终端(macOS Mohave 版本 10.14.6 18G87)不支持 Ctrl+D 作为 EOF。
我是怎么遇到这个问题的:
带getchar()
的代码附在下面,如果输入的字符不为空,基本上这段代码就是echo getchar(),否则,对于多个连续的空白字符,它只输出一个空白字符。
代码本身有效,但是当 运行 它在终端中时,终端不会将 Ctrl+D 视为 EOF,因此 代码永远不会终止。
我确定这是因为我错误地使用了 system ("/bin/stty raw");
和 system ("/bin/stty cooked");
,但是,我不知道如何解决它。
/* K&R C Exercise 1-9. Write a program to copy its input to its output,
* replacing each string of one or more blanks by a single blank.*/
#include <stdio.h>
#include <stdlib.h>
int main(void){
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
*
* */
system ("/bin/stty raw");
while ((ch=getchar())!= EOF){
if (ch != ' ' ){
if (prev == ' '){
putchar(prev);
putchar(ch);
}
else{
putchar(ch);
}
prev = ch;
}
else{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system ("/bin/stty cooked");
return 0;
}
我检查了 stty
,但是,它确实将 EOF
配置为 Ctrl +D
。但是,现在,如果我按 Ctrl + D
,它只会将终端从一个 window 拆分为两个。
如何才能允许 EOF
重新启用?
谢谢!
此代码适用于我的 Mac 运行 macOS Catalina 10.15。我希望它在几乎任何你可以接触到的类 Unix 系统上都能以基本相同的方式工作,包括旧版本的 macOS。它通过比较 ch
和 '[=12=]4'
来发现 control-D(八进制 4 — 在标准 C 中可写许多其他方式,包括仅 4
)键入并终止循环时。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int ch;
int prev = -1;
/* if you are in a UNIX like environment
* the ICANON flag is enabled by default, so input is buffered until the next '\n' or EOF
*
* */
system("/bin/stty raw");
while ((ch = getchar()) != EOF && ch != '[=10=]4')
{
if (ch != ' ')
{
if (prev == ' ')
{
putchar(prev);
putchar(ch);
}
else
{
putchar(ch);
}
prev = ch;
}
else
{
prev = ch;
continue;
}
}
/* use system call to set terminal behaviour to more normal behaviour */
system("/bin/stty cooked");
return 0;
}
当然,输出显示有点奇怪——例如,键入 return 不会将光标移动到下一行。但是 ch == '[=14=]4'
的测试确实检测到何时键入 control-D。 (space 消除代码也有效。)
使用 stty cbreak
而不是 stty raw
使中断启用,但通过 control-D 的 EOF 仍然被禁用。