สรุป
สำหรับกรณีการใช้งานจำนวนมากฟังก์ชันPOSIXisatty()
คือสิ่งที่จำเป็นในการตรวจสอบว่า stdin เชื่อมต่อกับเทอร์มินัลหรือไม่ ตัวอย่างเล็กน้อย:
#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;
}
ส่วนต่อไปนี้จะเปรียบเทียบวิธีการต่างๆที่สามารถใช้ได้หากต้องทดสอบระดับการโต้ตอบที่แตกต่างกัน
วิธีการในรายละเอียด
มีหลายวิธีในการตรวจสอบว่าโปรแกรมกำลังทำงานแบบโต้ตอบหรือไม่ ตารางต่อไปนี้แสดงภาพรวม:
cmd \ method ctermid open isatty fstat
-------------------------------------------------- ----------
./test / dev / tty ตกลงใช่ S_ISCHR
./test ≺ test.cc / dev / tty ตกลง NO S_ISREG
cat test.cc | ./test / dev / tty ตกลงไม่มี S_ISFIFO
เสียงสะท้อน. / ทดสอบ | ในขณะนี้ / dev / tty FAIL NO S_ISREG
ผลลัพธ์มาจากระบบ Ubuntu Linux 11.04 โดยใช้โปรแกรมต่อไปนี้:
#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;
}
อุปกรณ์ปลายทาง
ถ้าเซสชั่นแบบโต้ตอบความต้องการความสามารถบางอย่างคุณสามารถเปิดอุปกรณ์ปลายทางและ (ชั่วคราว) tcsetattr()
กำหนดแอตทริบิวต์ขั้วที่คุณต้องผ่าน
ตัวอย่าง Python
รหัสงูใหญ่ที่ตัดสินใจไม่ว่าจะเป็นล่ามทำงานโต้ตอบisatty()
การใช้งาน ฟังก์ชั่นPyRun_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);
โทร 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;
ที่โทรisatty()
.
ข้อสรุป
มีระดับการโต้ตอบที่แตกต่างกัน สำหรับการตรวจสอบว่าstdin
เชื่อมต่อกับไพพ์ / ไฟล์หรือเทอร์มินัลจริงisatty()
เป็นวิธีการที่เป็นธรรมชาติในการทำเช่นนั้น