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 기능은 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 OK YES S_ISCHR
./test < test.cc /dev/tty OK NO S_ISREG
cat test.cc | ./test /dev/tty OK NO S_ISFIFO
echo ./test | at now /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>
int main() {
char tty[L_ctermid+1];
ctermid(tty);
printf("ID: %s\n", tty);
int fd = open(tty, O_RDONLY);
if (fd < 0) perror("Could not open terminal");
else {
printf("Opened terminal\n");
struct termios term;
int r = tcgetattr(fd, &term);
if (r < 0) perror("Could not get attributes");
else printf("Got attributes\n");
}
if (isatty(fileno(stdin))) printf("Is a terminal\n");
else printf("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)) printf("S_ISCHR\n");
else if (S_ISFIFO(stats.st_mode)) printf("S_ISFIFO\n");
else if (S_ISREG(stats.st_mode)) printf("S_ISREG\n");
else printf("unknown stat mode\n");
}
return 0;
}
단말 장치
인터랙티브세션에 특정 기능이 필요한 경우 터미널 디바이스를 열고 (일시적으로) 를 사용하여 필요한 터미널 속성을 설정할 수 있습니다.tcsetattr().
Python의 예시
인터프리터가 인터프리터 실행 여부를 결정하는 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()자연스러운 방법이라고 생각합니다.
아마 다음과 같이 "stdin"이 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.
}
물론 Python은 오픈 소스이기 때문에 그들이 무엇을 하는지 보고 확실히 알 수 있습니다.
http://www.python.org/ftp/python/2.6.2/Python-2.6.2.tar.bz2
Windows 에서는, 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...
}
전화하시면 됩니다.stat(0, &result)확인하다!S_ISREG( result.st_mode )그건 Posix지 C/C++가 아니에요.
stat() 또는 fstat()을 호출하여 S_IFIFO가 st_mode로 설정되어 있는지 확인합니다.
언급URL : https://stackoverflow.com/questions/1312922/detect-if-stdin-is-a-terminal-or-pipe
'programing' 카테고리의 다른 글
| 쉼표로 구분된 문자열을 목록으로 변환하는 방법 (0) | 2022.07.21 |
|---|---|
| DEX를 Java 소스 코드로 디컴파일 (0) | 2022.07.21 |
| 개인 메서드, 필드 또는 내부 클래스가 있는 클래스를 테스트하려면 어떻게 해야 합니까? (0) | 2022.07.21 |
| Vuetify.js - 동적 카드 높이 애니메이션 (0) | 2022.07.21 |
| 열거값을 int로 변환하는 방법 (0) | 2022.07.21 |