答案 0 :(得分:1)
虽然我同意这些评论,即您通常应该信任用户,但这会尝试回答问题,因为我通过阅读评论来理解了该问题(“ 如果我的程序在后台运行,命令终端是可用且可操作的,但程序的输出会遮挡用户输入并替换提示“)。
这不会阻止程序运行,但是流向std::cout
的流将被丢弃,因此程序可以在不干扰用户的情况下运行。将输出重定向到文件或管道仍然可以。
#define _POSIX_SOURCE
#include <iostream>
#include <stdexcept>
#include <stdio.h> // fileno
#include <unistd.h> // isatty
#include <signal.h> // signal
#include <fcntl.h> // fcntl
#include <termios.h> // tcgetattr/tcsetattr
void handle_input(int /*sig*/) {
signal(SIGTTIN, SIG_IGN);
std::cin.setstate(std::ios::failbit);
}
void handle_output(int /*sig*/) {
signal(SIGTTOU, SIG_IGN);
std::cout.setstate(std::ios::failbit);
}
class TCAttr {
int m_fd;
termios m_attr;
public:
TCAttr(int fd) : m_fd(fd), m_attr() {
// get input, output and local attributes
if(tcgetattr(m_fd, &m_attr) != 0)
m_fd = -1;
}
TCAttr(FILE* fp) : TCAttr(fileno(fp)) {}
TCAttr() : m_fd(-1), m_attr() {}
~TCAttr() {
// restore original input, output and local attributes
if(m_fd>=0)
tcsetattr(m_fd, TCSADRAIN, &m_attr);
}
//
bool set_lmode(tcflag_t flag) {
termios tmp;
if(tcgetattr(m_fd, &tmp)!=0) return false;
tmp.c_lflag = flag;
return tcsetattr(m_fd, TCSADRAIN, &tmp)==0;
}
bool add_lmode(tcflag_t flag) {
termios tmp;
if(tcgetattr(m_fd, &tmp)!=0) return false;
tmp.c_lflag |= flag;
return tcsetattr(m_fd, TCSADRAIN, &tmp)==0;
}
bool remove_lmode(tcflag_t flag) {
termios tmp;
if(tcgetattr(m_fd, &tmp)!=0) return false;
tmp.c_lflag &= ~flag;
return tcsetattr(m_fd, TCSADRAIN, &tmp)==0;
}
};
int main() {
TCAttr tca(stdout);
if(isatty(fileno(stdin))) {
// if tty input is requested in background mode
// SIGTTIN will be sent
signal(SIGTTIN, handle_input);
}
if(isatty(fileno(stdout))) {
// if tty output is requested in background mode
// SIGTTOU will be sent
signal(SIGTTOU, handle_output);
tca.add_lmode(TOSTOP);
}
std::cout << "Thanks for not streaming to a tty in background mode\n";
std::string name;
std::cin >> name;
std::cout << name << "\n";
}
答案 1 :(得分:0)
这样做是不好的做法。 UNIX惯例是假定用户做正确的事并做出相应的调整。要么修改程序以使其能够在后台进程中正常运行,要么假定用户会将输出通过管道传输到/dev/null
或日志中。