사전 준비 없이 다른 터미널에서 실행 중인 프로세스의 터미널 장치 stdin에 어떻게 쓸 수 있습니까? [복사]

사전 준비 없이 다른 터미널에서 실행 중인 프로세스의 터미널 장치 stdin에 어떻게 쓸 수 있습니까? [복사]

다음과 같은 비슷한 질문이 많이 있는 것 같습니다.

https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-external-process

그러나 주어진 대답은 표준 입력을 파이프로 설정하여 프로그램을 미리 준비하는 것입니다.

게다가:

https://serverfault.com/questions/178457/can-i-send-some-text-to-the-stdin-of-an-active-process-running-in-a-screen-sessi

이는 관련 프로그램을 실행하는 터미널 멀티플렉서에 명령을 수행하여 응답합니다. 즉, 사전 준비도 필요합니다.

이 질문은 이를 수행하는 방법에 관한 것입니다.아니요미리 준비하십시오.

처음에는 이것이 간단할 것이라고 생각했습니다.

echo foo > /proc/$p/fd/0

하지만 이것은 터미널에만 기록됩니다. 그런 다음 다음을 시도했습니다.

echo foo > /proc/$terminal_emulator/fd/$ptmx_fd

그러나 이것은 에코를 위해 새로운 터미널 장치 슬레이브를 열기 때문에 실패합니다.

나는 gdb(한숨을 쉬다) 아래에 게시하겠지만 더 간단하고 더 나은 대안을 아는 사람이 있는지 궁금합니다.

답변1

#!/usr/bin/zsh

pid="$1"
stdin_data="$2"

for p in $(pstree -sp "$pid" | grep -Po '(?<=\()\d+(?=\))' | tac); do
  [[ -r "/proc/$p/fd" ]] || continue
  for f in /proc/$p/fd/*; do
    if [[ "$(readlink "$f")" = /dev/ptmx ]]; then
      fd="$(basename "$f")"
      break 2
    fi
  done
done

sudo gdb -p "$p" --batch -x =(printf '%s' '            
  p (int)write($fd, "$stdin_data", (int)strlen("$stdin_data"))
')

나는 스크립트 매개변수에 C를 주입할 수 있다는 점을 좋아하지 않습니다.

답변2

분명히 그럴 수 없습니다. 프로세스의 표준 입력 파일에 쓰면 프로세스가 추가한 내용을 읽지 않습니다. 전체 설명은 다음 답변을 참조하세요.https://serverfault.com/a/962956

관련 정보