命令输出(stdout,stderr)未重定向到管道

Posted

技术标签:

【中文标题】命令输出(stdout,stderr)未重定向到管道【英文标题】:Command output(stdout,stderr) not redirected to pipe 【发布时间】:2015-03-05 11:05:29 【问题描述】:

我在从专有二进制文件重定向 stdoutstderr 时遇到问题。

在使用 strace 工具进行一些“逆向工程”之后,我发现 stdout 描述符上有奇怪的 ioctl-call。

谁能解释一下这个电话是什么意思?

ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, B38400 opost isig icanon echo ...) = 0
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, B38400 opost isig icanon echo ...) = 0

【问题讨论】:

在管道传输时是否也会进行此调用?它可能正在测试 STDIN 和 STDOUT 是否在 tty 上。 它被调用,但如果进程是管道 ioctl 返回“= -1 ENOTTY(设备不适当的 ioctl)”(而不是“= 0”),然后写入标准输出不会发生......好吧,谢谢,现在我明白发生了什么。我可以欺骗过程或任何其他技巧将输出重定向到文件吗? 【参考方案1】:

没有什么奇怪的。它只是获取终端参数 - 即来自 xterm 您正在运行的 /dev/pts/X 设备的参数。

来自tcgetattr() 的手册页(与TCGETS 相同,参见man tty_ioctl):

tcgetattr() 获取与 fd 引用的对象关联的参数,并将它们存储在 termios_p 引用的 termios 结构中。该函数可以从后台进程调用;但是,终端属性可能随后会被前台进程更改。

【讨论】:

我还是不明白,它对标准流有何影响?如果我理解正确,它只会从 tty 获取参数 你能给我更多关于第三个 ioctl 参数的信息吗? @Dcow,是的,它获取tty 参数。 ioctl 调用中的第三个参数依赖于 ioctl。对于TCGETS ioctl,它是termios 结构,其中包含描述终端的各种标志:在您的情况下,它的 38400 是以比特/秒为单位的速度,echo 表示 tty显示输入字符等。

以上是关于命令输出(stdout,stderr)未重定向到管道的主要内容,如果未能解决你的问题,请参考以下文章

如何在实时输出的同时将命令的 stdout 和 stderr 重定向到控制台和日志文件?

重定向stdin stdout stderr |

输出重定向是不是按顺序写入 stdout 和 stderr 信息?

如何将stdout和stderr都重定向到文件[重复]

标准IO和重定向

如何将时间戳添加到 cronjob 输出的行并将 stdout 和 stderr 重定向到不同的进程和/或文件