在 C 中按 ctrl-c 隐藏 ^C

问题描述 投票:0回答:3

我正在创建自己的 shell,当任何 Linux 发行版上的任何用户按 ctrl+c 时,我想禁用 ^C。

我不需要处理信号SIGINT,我已经这样做了,因为不要在ctrl+c上停止程序。我只是想知道如何隐藏这两个字符^C

在我的程序开始时是否有任何要调用的函数或要设置的环境变量?

编辑

int a = fork(); if (!a) { char *cmd[] = {"/bin/stty", 0 }; char *cmd_args[] = {" ", "-echoctl", 0}; execve(cmd[0], cmd_args, env); }

尝试过这个。它删除了 ctrl-c 上的 ^C 但它仍然显示一个方形字符,就像无法显示该字符一样。好像是EOT(003 ascii)

c shell exit
3个回答
5
投票

^C

来自Linux终端驱动上的echo

这是一个用 C 编写的示例程序。它首先禁用保存当前设置,并注册一个

atexit

 处理程序以在程序退出时恢复设置,然后禁用标准输入终端上的 echo。然后就进入了一个无限的while循环。现在,当您在终端上键入任何内容时,都不会显示 
nothing,甚至连 ^C
 也不显示。

shell 使用的技巧是它们

完全取代终端上的输入处理,关闭规范输入处理,一次读取一个字符的标准输入,并自行处理回显 - 这需要更多代码比 Stack Overflow 答案中可能的代码要多。

#include <termios.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> struct termios saved; void restore(void) { tcsetattr(STDIN_FILENO, TCSANOW, &saved); } int main() { struct termios attributes; tcgetattr(STDIN_FILENO, &saved); atexit(restore); tcgetattr(STDIN_FILENO, &attributes); attributes.c_lflag &= ~ ECHO; tcsetattr(STDIN_FILENO, TCSAFLUSH, &attributes); printf("Entering the loop\n"); while(1) {}; }
    

3
投票
运行

stty -echoctl

应该隐藏它。请参阅
man stty
了解更多详情。


0
投票
您可以使用

ANSI转义码删除^C字符。 在处理 SIGINT 信号的函数中,打印将光标向左移动两次的字符,然后删除右侧直到行尾的所有字符。

下面的示例适用于 macOS 和 Raspberry Pi 操作系统。

在 Windows 上不需要这个技巧,因为按 ctrl+c 是无声的。

/** remove_ctrl_c.c gcc remove_ctrl_c.c -o remove_ctrl_c && ./remove_ctrl_c Remove the characters ^C with ANSI escape codes. (see https://en.wikipedia.org/wiki/ANSI_escape_code) \b : Move cursor one character on the left. \b : Idem \033[K : Delete all the characters on the right of the cursor until the end of the line. You can also use two spaces if you prefer, but they will be present in the output although they are not visible. \n : Add a new line. This is optional, but if you remove it and some characters are printed on the last line, the terminal will add an extra % character to indicate that the new line character was absent. Note that, as the printf command is buffered, we need to use the fflush command before the end of the program to force stdout to be updated. */ #include <stdio.h> #include <stdlib.h> #include <signal.h> volatile sig_atomic_t KEYBOARD_INTERRUPT = 0; void handleSignal(int signal) { KEYBOARD_INTERRUPT = 1; } int main() { signal(SIGINT, handleSignal); printf("Remove ^C on exit!"); fflush(stdout); while (!KEYBOARD_INTERRUPT) { } printf("\b\b\033[K\n"); fflush(stdout); return 0; }
    
© www.soinside.com 2019 - 2024. All rights reserved.