stdin이 터미널인지 파이프인지 감지합니까?
python
인수없이 터미널에서 " "을 실행 하면 Python 대화 형 셸이 나타납니다.
cat | python
터미널에서 " "를 실행하면 대화 형 모드가 시작되지 않습니다. 어쨌든 입력을받지 않고 파이프에 연결되어 있음을 감지했습니다.
C, C ++ 또는 Qt에서 유사한 감지를 어떻게 수행합니까?
사용 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");
(창에서는 밑줄로 시작합니다 : _isatty
, _fileno
)
요약
많은 사용 사례에서 POSIX 기능 isatty()
은 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 isatty fstat 열기 ――――――――――――――――――――――――――――――――――――――――――――――――― ―――――――――― ./test / dev / tty 확인 예 S_ISCHR ./test ≺ test.cc / dev / tty OK NO S_ISREG 고양이 test.cc | ./test / dev / tty OK NO S_ISFIFO echo ./test | 현재 / 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 예
The Python code that decides whether the interpreter runs interactively uses isatty()
. The Function 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);
calls 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;
which calls isatty()
.
Conclusion
There are different degrees of interactivity. For checking if stdin
is connected to a pipe/file or a real terminal isatty()
is a natural method to do that.
Call stat() or fstat() and see if S_IFIFO is set in st_mode.
On Windows you can use GetFileType.
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...
}
Probably they are checking the type of file that "stdin" is with fstat, something like this:
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.
}
Of course Python is open source, so you can just look at what they do and know for sure:
http://www.python.org/ftp/python/2.6.2/Python-2.6.2.tar.bz2
You can call stat(0, &result)
and check for !S_ISREG( result.st_mode )
. That's Posix, not C/C++, though.
참고URL : https://stackoverflow.com/questions/1312922/detect-if-stdin-is-a-terminal-or-pipe
'program story' 카테고리의 다른 글
JQuery-Mobile / Phonegap을 함께 사용하는 올바른 방법? (0) | 2020.08.07 |
---|---|
ASP.NET의 기본 세션 시간 제한은 무엇입니까? (0) | 2020.08.07 |
Python / Django : runserver에서 콘솔에 로그, Apache에서 파일에 로그 (0) | 2020.08.07 |
폴더가 잠겨있어 잠금을 해제 할 수 없습니다. (0) | 2020.08.07 |
언어는 언제 스크립팅 언어로 간주됩니까? (0) | 2020.08.06 |