Tóm lược
Đối với nhiều trường hợp sử dụng, chức năng POSIXisatty()
là tất cả những gì nó cần để phát hiện xem stdin có được kết nối với thiết bị đầu cuối hay không. Một ví dụ tối thiểu:
#include <unistd.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if (isatty(fileno(stdin)))
puts("stdin is connected to a terminal");
else
puts("stdin is NOT connected to a terminal");
return 0;
}
Phần sau đây so sánh các phương pháp khác nhau có thể được sử dụng nếu các mức độ tương tác khác nhau phải được kiểm tra.
Phương pháp chi tiết
Có một số phương pháp để phát hiện xem một chương trình có đang chạy tương tác hay không. Bảng sau hiển thị tổng quan:
cmd \ method ctermid open isatty fstat
―――――――――――――――――――――――――――――――――――――――――――――――――― ――――――――――
./test / dev / tty OK CÓ S_ISCHR
./test ≺ test.cc / dev / tty OK KHÔNG S_ISREG
cat test.cc | ./test / dev / tty OK KHÔNG S_ISFIFO
echo ./test | hiện tại / dev / tty FAIL NO S_ISREG
Kết quả là từ hệ thống Ubuntu Linux 11.04 sử dụng chương trình sau:
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <iostream>
using namespace std;
int main() {
char tty[L_ctermid+1] = {0};
ctermid(tty);
cout << "ID: " << tty << '\n';
int fd = ::open(tty, O_RDONLY);
if (fd < 0) perror("Could not open terminal");
else {
cout << "Opened terminal\n";
struct termios term;
int r = tcgetattr(fd, &term);
if (r < 0) perror("Could not get attributes");
else cout << "Got attributes\n";
}
if (isatty(fileno(stdin))) cout << "Is a terminal\n";
else cout << "Is not a terminal\n";
struct stat stats;
int r = fstat(fileno(stdin), &stats);
if (r < 0) perror("fstat failed");
else {
if (S_ISCHR(stats.st_mode)) cout << "S_ISCHR\n";
else if (S_ISFIFO(stats.st_mode)) cout << "S_ISFIFO\n";
else if (S_ISREG(stats.st_mode)) cout << "S_ISREG\n";
else cout << "unknown stat mode\n";
}
return 0;
}
Thiết bị thập phân
Nếu phiên tương tác cần một số khả năng nhất định, bạn có thể mở thiết bị đầu cuối và (tạm thời) đặt các thuộc tính đầu cuối bạn cần thông qua tcsetattr()
.
Ví dụ Python
Các mã Python rằng quyết định liệu người phiên dịch chạy tương tác sử dụng isatty()
. Chức năngPyRun_AnyFileExFlags()
/* Parse input from a file and execute it */
int
PyRun_AnyFileExFlags(FILE *fp, const char *filename, int closeit,
PyCompilerFlags *flags)
{
if (filename == NULL)
filename = "???";
if (Py_FdIsInteractive(fp, filename)) {
int err = PyRun_InteractiveLoopFlags(fp, filename, flags);
cuộc gọi Py_FdIsInteractive()
/*
* The file descriptor fd is considered ``interactive'' if either
* a) isatty(fd) is TRUE, or
* b) the -i flag was given, and the filename associated with
* the descriptor is NULL or "<stdin>" or "???".
*/
int
Py_FdIsInteractive(FILE *fp, const char *filename)
{
if (isatty((int)fileno(fp)))
return 1;
cuộc gọi nào isatty()
.
Phần kết luận
Có các mức độ tương tác khác nhau. Để kiểm tra xem stdin
được kết nối với một đường ống / tệp hoặc một thiết bị đầu cuối thực isatty()
là một phương pháp tự nhiên để thực hiện điều đó.