স্টিডিনটি টার্মিনাল বা পাইপ কিনা তা নির্ধারণ করুন?


118

আমি যখন pythonকোনও আর্গুমেন্ট ছাড়াই টার্মিনাল থেকে চালিত করি এটি পাইথন ইন্টারেক্টিভ শেলটি উপস্থিত করে।

আমি যখন cat | pythonটার্মিনাল থেকে " " চালিত করি এটি ইন্টারেক্টিভ মোডটি আরম্ভ করে না। কোনওভাবে, কোনও ইনপুট না পেয়ে, এটি আবিষ্কার হয়েছে যে এটি একটি পাইপের সাথে সংযুক্ত।

আমি কীভাবে সি বা সি ++ বা কিউটিতে অনুরূপ সনাক্ত করব?


7
আপনি যা চান তা স্টিডিন পাইপ কিনা তা সনাক্ত করা নয়, তবে স্টিডিন / স্টাডআউট যদি টার্মিনাল হয়।
জুলিয়ানো

উত্তর:


137

ব্যবহার isatty:

#include <stdio.h>
#include <io.h>
...    
if (isatty(fileno(stdin)))
    printf( "stdin is a terminal\n" );
else
    printf( "stdin is a file or a pipe\n");

(Windows এ তারা আন্ডারস্কোর সঙ্গে পূর্বে সমাধান করছেন যারা _isatty, _fileno)


13
+1: স্টিডিন একটি পাইপ হতে পারে বা কোনও ফাইল থেকে পুনঃনির্দেশিত হতে পারে। যদি এটা ভালো চেক করতে হয় ইন্টারেক্টিভ যদি তা না হয় চেক করতে চেয়ে না
জন কুগেলম্যান

51
POSIX উপর সেখানে নেই io.hএবং জন্য isatty()আপনি অন্তর্ভুক্ত করতে হবে unistd.h
ম্যাক্সচলেপজিগ

ফলোআপ প্রশ্ন: স্টিডিন যদি টিটিটি না হয় তবে পাইপযুক্ত সামগ্রীগুলি কীভাবে পড়বেন? stackoverflow.com/q/16305971/96656
ম্যাথিয়াস Bynens

দ্রষ্টব্য: আপনি যদি আউটপুটটি পাইপ করা হয় তবে আউটপুট দমন করতে চান সেই ক্ষেত্রে যদি আপনি আপনার আউটপুট- টিটিটি কিনা তা দেখতে চাইলে আপনাকে স্টডআউট (STDOUT_FILENO) পরীক্ষা করে দেখতে হবে less
করূস

71

সারসংক্ষেপ

অনেকগুলি ব্যবহারের ক্ষেত্রে পসিক্স ফাংশন isatty()হ'ল স্টিডিন কোনও টার্মিনালের সাথে সংযুক্ত থাকলে তা সনাক্ত করা দরকার। একটি সর্বনিম্ন উদাহরণ:

#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;
}

নিম্নলিখিত বিভাগে বিভিন্ন পদ্ধতির তুলনা করা হয়েছে যা ইন্টারেক্টিভিটির বিভিন্ন ডিগ্রি পরীক্ষা করতে হলে ব্যবহার করা যেতে পারে।

বিস্তারিত পদ্ধতি Meth

কোনও প্রোগ্রাম ইন্টারেক্টিভভাবে চলছে কিনা তা সনাক্ত করার জন্য বেশ কয়েকটি পদ্ধতি রয়েছে। নিম্নলিখিত সারণী একটি ওভারভিউ দেখায়:

সেন্টিমিডি \ পদ্ধতি সিটারমিড ওপেন ইসাটি ফেস্ট্যাট
-------------------------------------------------- ----------
./est / dev / tty ঠিক আছে হ্যাঁ S_ISCHR
./test ≺ test.cc / dev / tty ঠিক নেই S_ISREG
বিড়াল test.cc ./test / dev / tty ঠিক নেই কোনও S_ISFIFO
প্রতিধ্বনি। / টেষ্ট | এখনই / ডিভ / টিটিএফএইচ কোনও নম্বর নেই_এসআরইজি

ফলাফলগুলি নিম্নলিখিত প্রোগ্রামটি ব্যবহার করে একটি উবুন্টু লিনাক্স 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()

পাইথন উদাহরণ

পাইথন কোড যা সিদ্ধান্ত নেয় অনুবাদক ইন্টারেক্টিভ রান কিনা ব্যবহারসমূহ 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()এটি করার একটি প্রাকৃতিক পদ্ধতি।


5

সম্ভবত তারা "স্টিডিন" fstat এর সাথে থাকা ফাইলের ধরণটি পরীক্ষা করছে, এরকম কিছু:

struct stat stats;
fstat(0, &stats);
if (S_ISCHR(stats.st_mode)) {
    // Looks like a tty, so we're in interactive mode.
} else if (S_ISFIFO(stats.st_mode)) {
    // Looks like a pipe, so we're in non-interactive mode.
}

অবশ্যই পাইথন ওপেন সোর্স, সুতরাং আপনি কেবল তারা কী করেন তা দেখতে পারেন এবং নিশ্চিতভাবে জানতে পারেন:

http://www.python.org/ftp/python/2.6.2/Python-2.6.2.tar.bz2


4

উইন্ডোজ এ আপনি গেটফাইলটাইপ ব্যবহার করতে পারেন।

HANDLE hIn = GetStdHandle(STD_INPUT_HANDLE);
DWORD type = GetFileType(hIn);
switch (type) {
case FILE_TYPE_CHAR: 
    // it's from a character device, almost certainly the console
case FILE_TYPE_DISK:
    // redirected from a file
case FILE_TYPE_PIPE:
    // piped from another program, a la "echo hello | myprog"
case FILE_TYPE_UNKNOWN:
    // this shouldn't be happening...
}

3

স্ট্যাট () বা fstat () কল করুন এবং দেখুন S_IFIFOটি st_mode এ সেট করা আছে কিনা।


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.