我正在写寻呼机pspg.我必须解决以下问题.读完之后,stdin我应该stdin从之前的阅读管道重新分配到终端阅读.
我用了
freopen("/dev/tty", "r", stdin)
Run Code Online (Sandbox Code Playgroud)
但是,当从命令中使用寻呼机时,它不起作用
su - someuser -c 'export PAGER=pspg psql somedb'
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我收到一个错误:没有这样的设备或地址.
我找到了一个解决方法 - 现在,代码看起来像:
if (freopen("/dev/tty", "r", stdin) == NULL)
{
/*
* try to reopen pty.
* Workaround from:
* https://cboard.cprogramming.com/c-programming/172533-how-read-pipe-while-keeping-interactive-keyboard-c.html
*/
if (freopen(ttyname(fileno(stdout)), "r", stdin) == NULL)
{
fprintf(stderr, "cannot to reopen stdin: %s\n", strerror(errno));
exit(1);
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,检测分配的终端设备的正确方法是什么?
但这种解决方法不正确.它解决了一个问题,但接下来就要来了.当某个用户与当前用户不同时,重新打开失败,并显示" 权限被拒绝"错误.因此,此解决方法不能用于我的目的.
小智 2
在这种情况下,会less回退到 fd 2 (stderr)。如果 stderr 已从 tty 重定向,它会放弃尝试获取键盘输入,而只打印整个输入流而不进行分页。
的设计su不允许有任何更好的事情。新用户正在原始用户拥有的 tty 上运行命令,而这个令人不快的事实无法完全隐藏。
这是一个很好的替代品,su没有这个问题:
ssh -t localhost -l username sh -c 'command'
Run Code Online (Sandbox Code Playgroud)
当然,它有更多的开销。