PTY 클래스

PTY 클래스

의사 터미널(PTY, pseudo-terminal)을 만들고 관리하는 클래스예요. (참고: en.wikipedia.org/wiki/Pseudo_terminal)

PTY를 쓰면 ::open으로 새 터미널을 할당하거나, ::spawn으로 특정 명령을 실행하는 새 터미널을 띄울 수 있어요.

출처: Ruby 3.3 API

본문

예시 (Example)

이 예시에서는 factor 명령의 stdout 버퍼링 방식이 stdio를 쓴다고 가정하고, 버퍼링 타입을 바꿔 볼게요.

PTY.open 대신 IO.pipe를 쓰면, factor의 stdout이 완전히 버퍼링되기 때문에 이 코드는 데드락에 걸려요.

# start by requiring the standard library PTY
require 'pty'

master, slave = PTY.open
read, write = IO.pipe
pid = spawn("factor", :in=>read, :out=>slave)
read.close     # we dont need the read
slave.close    # or the slave

# pipe "42" to the factor command
write.puts "42"
# output the response from factor
p master.gets #=> "42: 2 3 7\n"

# pipe "144" to factor and print out the response
write.puts "144"
p master.gets #=> "144: 2 2 2 2 3 3\n"
write.close # close the pipe

# The result of read operation when pty slave is closed is platform
# dependent.
ret = begin
        master.gets     # FreeBSD returns nil.
      rescue Errno::EIO # GNU/Linux raises EIO.
        nil
      end
p ret #=> nil

라이선스 (License)

© Copyright 1998 by Akinori Ito.

이 소프트웨어는 본 저작권 고지가 모든 복사본에 포함되는 한, 전체든 일부든 이 목적을 위해 자유롭게 재배포될 수 있어요.

이 소프트웨어는 명시적이든 암시적이든 일체의 보증 없이 "있는 그대로" 제공돼요. 적합성 보증이나 상품성, 사용 결과로 얻은 결과에 대한 보증을 포함하되 이에 국한되지 않아요.

Public Class Methods

check(pid, raise = false) → Process::Status or nil

pid로 지정된 자식 프로세스의 상태를 확인해요. 프로세스가 아직 살아 있으면 nil을 반환해요.

프로세스가 살아 있지 않고 raise가 true라면 PTY::ChildExited 예외를 던져요. 그렇지 않으면 Process::Status 인스턴스를 반환해요.

pid

getpty

::spawn의 별칭이에요.

open → [master_io, slave_file]

pty(의사 터미널)를 할당해요.

블록 형식에서는 두 원소 배열(master_io, slave_file)을 블록에 넘겨주고, 블록의 반환값이 open의 반환값이 돼요.

블록이 끝나면 아직 닫히지 않은 IOFile은 모두 닫혀요.

PTY.open {|master, slave|
  p master      #=> #<IO:masterpty:/dev/pts/1>
  p slave       #=> #<File:/dev/pts/1>
  p slave.path  #=> "/dev/pts/1"
}

블록 없는 형식에서는 두 원소 배열 [master_io, slave_file]을 반환해요.

master, slave = PTY.open

# do something with master for IO, or the slave file

두 형식 모두에서 master_io에 대해선 IO#raw!를 써서 개행 변환을 끌 수 있어요.

require 'io/console'

PTY.open {|m, s|
  s.raw!  # ...
}

spawn([env,] command_line) { |r, w, pid| ... }

새로 할당한 pty에서 지정한 명령을 실행해요. 별칭 ::getpty도 사용할 수 있어요.

명령의 제어 tty는 pty의 slave 디바이스로 설정되고, 표준 입출력·표준 에러도 slave 디바이스로 리다이렉트돼요.

env는 실행되는 pty에 추가 환경변수를 제공하는 선택 해시예요.

# sets FOO to "bar"
PTY.spawn({"FOO" => "bar"}, "printenv", "FOO") { |r, w, pid|
  p r.read
} #=> "bar\r\n"

# unsets FOO
PTY.spawn({"FOO" => nil}, "printenv", "FOO") { |r, w, pid|
  p r.read
} #=> ""

command, command_line은 실행할 전체 명령으로, String으로 주어져요. 추가 arguments는 명령으로 전달돼요.

반환값 (Return values)

블록 없는 형식에서는 크기 3의 배열 [r, w, pid]을 반환해요.

블록 형식에서는 이 값들이 블록에 넘겨져요.

r: pty에서 읽을 Reader입니다. w: pty에 쓸 Writer입니다. pid: 실행된 명령의 프로세스 ID입니다.