SSH如何忽略标准输出/错误重定向,直接写入控制台?
SSH如何忽略重定向,仍直接向控制台输出内容?
执行以下命令时,尽管已将标准输出和错误重定向到文件,但控制台依然会显示主机密钥确认的交互提示:
.\ssh.exe user@127.0.0.1 -p 1022 -v > test.log 2>&1
控制台显示内容:
The authenticity of host '[127.0.0.1]:1022 ([127.0.0.1]:1022)' can't be established. ED25519 key fingerprint is SHA256:xeS1I/8fteLkGqn43X0VkBpBgY7IIAo9Ysy69r/8iHQ. This key is not known by any other names. Are you sure you want to continue connecting (yes/no/[fingerprint])?
我知道该消息用于交互,重定向无意义,但这一机制是如何实现的?
SSH中负责该功能的核心函数如下:
static int confirm(const char *prompt, const char *fingerprint) { const char *msg, *again = "Please type 'yes' or 'no': "; const char *again_fp = "Please type 'yes', 'no' or the fingerprint: "; char *p, *cp; int ret = -1; if (options.batch_mode) return 0; for (msg = prompt;;msg = fingerprint ? again_fp : again) { cp = p = read_passphrase(msg, RP_ECHO); if (p == NULL) return 0; p += strspn(p, " "); /* skip leading whitespace */ p[strcspn(p, " ")] = '\0'; /* remove trailing whitespace */ if (p[0] == '\0' || strcasecmp(p, "no") == 0) ret = 0; else if (strcasecmp(p, "yes") == 0 || (fingerprint != NULL && strcmp(p, fingerprint) == 0)) ret = 1; free(cp); if (ret != -1) return ret; } }
其中prompt包含要显示的控制台字符串,关键逻辑在read_passphrase(msg, RP_ECHO)中,其实现原理如下:
核心机制:绕过标准流,直接操作终端设备
read_passphrase并没有使用被重定向的stdout/stdin标准IO流,而是直接与用户的交互终端设备绑定:
- Windows系统:调用系统API获取控制台的专属句柄,通过
WriteConsole输出提示、ReadConsole读取输入,完全不受标准流重定向的影响。 - Linux/Unix系统:尝试打开
/dev/tty设备文件,这个文件始终指向当前用户正在使用的交互终端,读写这个文件就等同于直接与控制台交互,和stdin/stdout的重定向状态无关。
这种设计是为了确保敏感的交互式操作(如主机密钥确认、密码输入)必须直接和用户交互,避免因重定向导致信息丢失或被写入文件,保障SSH的交互安全性和可靠性。
内容的提问来源于stack exchange,提问作者FireEmerald
相关产品推荐
相关产品推荐

