ctrl我正在创建自己的 shell,当任何 Linux 发行版上的任何用户按+时,我想禁用 ^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);
}
Run Code Online (Sandbox Code Playgroud)
试过这个。它删除了 ctrl-c 上的 ^C 但它仍然显示一个方形字符,就像无法显示该字符一样。好像是 EOT (003 ascii)
来自^CLinux中终端驱动程序的echo
下面是一个 C 语言示例程序。它首先禁用保存当前设置,并注册一个atexit处理程序以在程序退出时恢复设置,然后禁用标准输入终端上的 echo。然后就进入了一个无限的while循环。现在,当您在终端上键入任何内容时,都不会显示任何内容^C,甚至连那个 都不会显示。
shell 使用的技巧是它们完全取代了终端上的输入处理,关闭规范输入处理,一次读取一个字符的标准输入,并自行处理回显 - 这需要比原来更多的代码可能在堆栈溢出答案中。
#include <termios.h>
#include <unistd.h>
#include <stdlib.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) {};
}
Run Code Online (Sandbox Code Playgroud)
您可以使用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;
}
Run Code Online (Sandbox Code Playgroud)