这条消息是在哪里打印出来的?

这条消息是在哪里打印出来的?

我在 Alpine Linux 中工作,我无法理解 shell 的以下行为sh

/ # vsftpd /etc/vsftpd/vsftpd.conf > /dev/null
500 OOPS: bad bool value in config file for: hide_ids
/ # vsftpd /etc/vsftpd/vsftpd.conf 2> /dev/null
500 OOPS: bad bool value in config file for: hide_ids

消息在哪里打印出来?是stdout还是stderr

答案1

来源vsftpd将常数 定义VSFTP_COMMAND_FD为数字零。这恰好是写入错误的文件描述符。

$ grep -F VSFTP_COMMAND_FD defs.h
#define VSFTP_COMMAND_FD        0

不管看起来多么奇怪,代码正在将错误消息写入标准输入溪流。

void
bug(const char* p_text)
{
  /* Rats. Try and write the reason to the network for diagnostics */
  vsf_sysutil_activate_noblock(VSFTP_COMMAND_FD);
  (void) vsf_sysutil_write_loop(VSFTP_COMMAND_FD, "500 OOPS: ", 10);
  (void) vsf_sysutil_write_loop(VSFTP_COMMAND_FD, p_text,
                                vsf_sysutil_strlen(p_text));
  (void) vsf_sysutil_write_loop(VSFTP_COMMAND_FD, "\r\n", 2);
  vsf_sysutil_exit(2);
}

测试:

$ ./vsftpd >/dev/null
500 OOPS: vsftpd: must be started as root (see run_as_launching_user option)
$ ./vsftpd 2>/dev/null
500 OOPS: vsftpd: must be started as root (see run_as_launching_user option)
$ ./vsftpd </dev/null
$

因此,重定向/dev/null到应用程序可以消除错误。您还可以用来0>/dev/null表明您的意图,即丢弃应用程序发送到该特定文件描述符的任何输出。

答案2

vsftpd通常通过其 fd 0 (stdin) 来调用,inetd该 fd 0 (stdin) 是来自客户端的 TCP 命令套接字。

这就是它写入状态消息的地方。

你可以这样做:

vsftpd configfile < /dev/null

让它消失,而不是让它做任何有用的事情。

答案3

首先,该消息不是来自 shell。hide_ids是 vsftpd 的配置选项,而不是 shell 的配置选项,因此没有理由假设 shell 会打印引用它的任何内容。 (是的,有区别,而且很重要。)

其次,您已经显示 vsftpd 启动时 stdout 和 stderr 都重定向到,/dev/null并且它仍然可见,因此我们必须假设消息被打印到两者都不

某些实用程序通过 显式打开当前终端的新句柄/dev/tty,通常是为了执行需要用户交互的操作,而不会干扰可能的重定向。这就是 SSH 客户端如何询问您的密码,即使 stdout 和 stderr 都被重定向。

然而,这里的情况也不是这样。作为库萨拉南达的回答说,vsftpd 将致命错误打印到命令 fd(VSFTP_COMMAND_FD在源代码中指定)。据推测它也使用相同的 fd 来读取命令,并且它被定义为 fd 0,或者标准输入。这确实有效,因为所有 stdin、stdout 和 stderr 通常都是以读写方式打开的。在 Linux 上,您可以通过查看/proc/<pid>/fd正常启动的进程的条目权限来检查这一点。最简单的做法是ls

$ ls -l /proc/self/fd
total 0
lrwx------ 1 ilkkachu ilkkachu 64 Jan  1 13:54 0 -> /dev/pts/18
lrwx------ 1 ilkkachu ilkkachu 64 Jan  1 13:54 1 -> /dev/pts/18
lrwx------ 1 ilkkachu ilkkachu 64 Jan  1 13:54 2 -> /dev/pts/18
lr-x------ 1 ilkkachu ilkkachu 64 Jan  1 13:54 3 -> /proc/8955/fd/

0、1、2都被标记为rwx,因此它们以读写模式打开。 (我不确定这个x位在这里意味着什么,如果有的话。)

答案4

您重定向stdout/dev/null.所以不可能stdout。这留下了stderr

重定向stderr/dev/null,来检验这个假设。

相关内容