防止 control-D 在终端中回显

发布于 2025-01-14 14:19:59 字数 794 浏览 2 评论 0原文

当我使用 readline 函数并输入 control-D 告诉我的程序它到达 EOF 时,^D 在终端中回显。

我想删除它或用另一条消息替换它。

我尝试了 stty -echoctl 命令,但它不起作用。

我将 ZSH 与 Oh My Zsh 和 iTerm2 一起使用。

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<unistd.h>
# include<sys/types.h>
# include<sys/wait.h>
# include<readline/readline.h>
# include<readline/history.h>

int input(void)
{
    char    *buf;
 
    buf = readline("Please write the argument:\n");
    if (buf == NULL)
    {
        printf("Quitting the program\n");
        exit(0);
    }
    return (0);
}

int main()
{
    while (1)
    {
        if(!input())
            continue;
    }
    return (0);
}

我不知道现在可以尝试什么,我检查了很多 Stack Overflow 线程,但没有找到任何东西。

When I use readline function and type control-D to tell my program it reached EOF, ^D is echoed in the terminal.

I would like to remove it or to replace it by another message.

I tried stty -echoctl command but it doesn't work.

I'm using ZSH with Oh My Zsh and iTerm2.

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
# include<unistd.h>
# include<sys/types.h>
# include<sys/wait.h>
# include<readline/readline.h>
# include<readline/history.h>

int input(void)
{
    char    *buf;
 
    buf = readline("Please write the argument:\n");
    if (buf == NULL)
    {
        printf("Quitting the program\n");
        exit(0);
    }
    return (0);
}

int main()
{
    while (1)
    {
        if(!input())
            continue;
    }
    return (0);
}

I don't know what I can try now, I checked lots of Stack Overflow threads and didn't find anything.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

活雷疯 2025-01-21 14:19:59

虽然看起来您正在使用 readline 库,但实际上您正在使用构建在 BSD libedit 库,这是 Mac OS 默认提供的。因此,您可以预期某些事情的工作方式会有所不同。

不幸的是,libedit 没有详细的文档记录。似乎可以通过在主目录中创建一个文件名 .editrc 并插入以下行来修改 Ctrl-D 键的绑定:

bind ^D ed-end-of-file

这会将更改应用到使用该键的所有应用程序libedit 库,这可能有点激烈。要使其仅适用于您的程序,您可以

    rl_readline_name = "progname";

在程序的开头、第一次调用 readline 之前插入以下行:。将 progname 更改为您想要用作程序标记的任何名称。然后,您可以将 editrc 命令更改为以下内容(对 progname 使用相同的标记):

progname:bind ^D ed-end-of-file

至少,这在 Ubuntu 系统上有效。

另一种选择是在 Mac 上安装 GNU readline。根据 GNU readline 主页

MacOS X 用户可以从 MacPorts 获取 readline-8.0 的 MacOS X 软件包, readline-7.0 来自 Fink,或者readline-8.0 来自 Homebrew

然后你必须确保使用 GNU readline 而不是 libedit shim 构建你的程序。

这样做也将使提示按其读取的方式工作(即提示包含换行符)。但我不知道这是否是你想要的。

Although it looks like you are using the readline library, you're actually using a compatibility layer built on top of the BSD libedit library, which is what is provided by default by Mac OS. So you can expect some things to work a bit differently.

Unfortunately, libedit is not well-documented. It appears to be possible to modify the binding of the Ctrl-D key by creating a file name .editrc in your home directory, and inserting the line:

bind ^D ed-end-of-file

That will apply the change to all applications which use the libedit library, which may be a bit drastic. To make it apply only to your program, you can insert the line:

    rl_readline_name = "progname";

at the beginning of your program, before the first time you call readline. Change progname to whatever you want to use as a tag for your program. Then you can change the editrc command to the following (using the same tag for progname):

progname:bind ^D ed-end-of-file

At least, that worked on an Ubuntu system.

Another option would be to just install GNU readline on your Mac. According to the GNU readline home page:

MacOS X users may obtain MacOS X packages for readline-8.0 from MacPorts, readline-7.0 from Fink, or readline-8.0 from Homebrew.

Then you'll have to make sure you build your program with GNU readline instead of the libedit shim.

Doing that will make also make the prompt work the way it reads (i.e., the prompt includes a newline). I don't know if that's what you want, though.

孤独陪着我 2025-01-21 14:19:59

您需要做的基本上是拥有一个读取并手动打印每个字符的函数,以便您可以拦截不应该打印的字符。这是一个开始的想法:

int ch;
char buf[SIZE] = {0};
char *p = buf;

while(1) {
    ch = getchar();
    if(ch == EOF) { 
        p[1] = 0;
        break;
    }
    putchar(ch);
    *p++ = ch;
}

您可能希望以特殊的方式处理退格'\b'。与递减 p 类似,但要注意是否超出范围。

What you need to do is basically to have a function that reads AND manually print every character so that you can intercept characters that shouldn't be printed. Here is an idea to get started:

int ch;
char buf[SIZE] = {0};
char *p = buf;

while(1) {
    ch = getchar();
    if(ch == EOF) { 
        p[1] = 0;
        break;
    }
    putchar(ch);
    *p++ = ch;
}

You would probably like to treat backspace '\b' in a special way. Like decrementing p, but watch out for going out of bounds.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文