한 콘솔의 표준 입력에서 다른 콘솔로 읽는 프로세스에 대한 텍스트 입력을 어떻게 종료합니까? - 일반적으로 Enter 키를 누르면 수행되는 작업입니다.
콘솔 1: 사용자가 Enter를 누르지 않는 한(정상 동작) C++ 프로그램은 std::cin에서 데이터를 읽습니다.
콘솔 2: 일반 콘솔에서는 다음을 통해 콘솔 1의 프로세스에 텍스트를 보낼 수 있다는 것을 알았습니다.
echo "some text" >> /proc/18672/fd/0
(PID가 18672인 내 프로세스의 표준 입력에 기록합니다.)
이 방법은 작동하지만 중요한 단계가 누락되었습니다.
콘솔 2에서 "일부 텍스트"를 입력하려면 어떻게 해야 합니까? 또는 콘솔 2에서 콘솔 1의 Enter 키 누르기를 시뮬레이션하려면 어떻게 해야 합니까?
개행 문자(예: "\n")를 사용해도 효과가 없습니다.
답변1
다른 방식으로 설계하는 것이 더 나을 것이라는 데에는 의심의 여지가 없습니다(OpenBSD는 TIOCSTI ioctl에 대한 지원을 제거했습니다). 이를 염두에 두고 먼저 .NET std::cin
에서 작동하도록 만드는 적절한 C++ 코드가 필요합니다 /dev/pts/0
.
$ cat foo.cpp
#include <iostream>
int main() {
int n;
std::cin >> n;
std::cout << n;
}
$ c++ foo.cpp
$ tty
/dev/pts/0
$ ./a.out
그런 다음 다른 터미널에서 컴파일합니다.
// ttytickle.c - send characters via TIOCSTI
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <err.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
int fd = open(*++argv, O_WRONLY);
if (fd < 0) err(1, "open failed '%s'", *argv);
char word[] = "42\n";
char *wp = word;
while(*wp != '\0') ioctl(fd, TIOCSTI, wp++);
return 0;
}
위의 명령을 실행하십시오.
$ make ttytickle && ./ttytickle /dev/pts/0
cc ttytickle.c -o ttytickle
그리고 (TIOCSTI가 지원된다고 가정하면 문자열은 너무 길지 않습니다. 등) 터미널 ./a.out
에서 실행하면 /dev/pts/0
42가 인쇄되어야 합니다.
하지만 원하는 작업을 파이프나 소켓 등을 통해 다른 방식으로 설계하는 것이 더 좋습니다.
답변2
프로세스의 표준 입력은 터미널에만 연결되어 있습니다. 이를 보려면 목록을 만드세요.
> ll /proc/self/fd
total 0
lrwx------ 1 root root 64 Sep 12 11:32 0 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 11:32 1 -> /dev/pts/1
lrwx------ 1 root root 64 Sep 12 11:32 2 -> /dev/pts/1
따라서 에코 "텍스트"는 보시다시피 실제로 해당 터미널로 출력됩니다. 달성하고자 하는 것이 프로세스에 입력을 보내는 것이라면 FIFO가 귀하의 요구 사항에 적합할까요? 예를 들어:
on tty1:
$ mkfifo input
$ cat > input <<-eof # send process some input (being careful not to close your output before completely done)
echo Hi
echo World
read ans
42
echo \$ans
eof
두 번째 프로세스는 "입력" FIFO에서 읽습니다.
e.g. on tty1, in the same directory with the "input" fifo:
$ bash -x < input
+ echo Hi
Hi
+ echo World
World
+ read ans
+ echo 42
42