프로세스

프로세스 (Processes)

여기서는 Racket에서 외부 프로세스를 실행하고 통신하는 방법을 다뤄요. subprocess로 저수준 프로세스 생성과 입출력 포트 연동을 하고, racket/systemsystem, process 계열로 셸 명령 실행을 지원해요.

출처: Racket Reference

본문

(subprocess stdout stdin stderr [group] command arg ...)
  → subprocess?
    (or/c (and/c input-port? file-stream-port?) #f)
    (or/c (and/c output-port? file-stream-port?) #f)
    (or/c (and/c input-port? file-stream-port?) #f)
  stdout : (or/c (and/c output-port? file-stream-port?) #f)
  stdin : (or/c (and/c input-port? file-stream-port?) #f)
  stderr : (or/c (and/c output-port? file-stream-port?) #f 'stdout)
  group : (or/c #f 'new subprocess) = (and (subprocess-group-enabled) 'new)
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)

(subprocess stdout stdin stderr [group] command exact arg)
  → subprocess?
    (or/c (and/c input-port? file-stream-port?) #f)
    (or/c (and/c output-port? file-stream-port?) #f)
    (or/c (and/c input-port? file-stream-port?) #f)
  stdout : (or/c (and/c output-port? file-stream-port?) #f)
  stdin : (or/c (and/c input-port? file-stream-port?) #f)
  stderr : (or/c (and/c output-port? file-stream-port?) #f)
  group : (or/c #f 'new subprocess) = (and (subprocess-group-enabled) 'new)
  command : path-string?
  exact : 'exact
  arg : string?

기본 운영 체제에서 command를 비동기적으로 실행하는 새 프로세스를 만들고, 새 프로세스에 current-environment-variables 환경 변수들을 제공해요. racket/systemsystemprocess도 함께 보세요.

Unix와 Mac OS에서 하위 프로세스 생성은 command가 가리키는 프로그램 시작과는 별개예요. 특히 command가 존재하지 않거나 실행 불가능한 파일을 가리키면, 오류는 생성 프로세스가 아니라 하위 프로세스에서 (표준 오류와 0이 아닌 종료 코드를 통해) 보고돼요.

command 인자는 프로그램 실행 파일의 경로이고, arg들은 프로그램의 명령줄 인자예요. PATH 환경 변수에 기반해 실행 파일을 찾으려면 find-executable-path를 보세요. Unix와 Mac OS에서 명령줄 인자는 바이트 문자열로 전달되고, 문자열 인자는 현재 로케일의 인코딩으로 변환돼요(인코딩과 로케일 참고). Windows에서 명령줄 인자는 문자열로 전달되고, 바이트 문자열은 UTF-8로 변환돼요.

Windows에서 프로세스는 기본적으로 단일 명령줄 인자 문자열을 받는데, Unix와 Mac OS 프로세스가 인자 배열을 기본적으로 받는 것과 달라요. Windows 명령줄 문자열은 일반 응용 프로그램이 다시 인자 배열로 파싱할 수 있도록 Windows 관례에 따라 commandarg로부터 구성돼요. Windows 명령줄 관례에 대한 정보는 Microsoft 문서 소스나 http://msdn.microsoft.com/ 에서 "command line parsing"을 검색해 보세요. 하지만 응용 프로그램이 명령줄을 다른 방식으로 파싱할 수 있다는 점을 조심하세요. 특히 ".bat" 또는 ".cmd" 파일을 가리키는 명령을 제공할 때 각별히 주의하세요. 프로세스에 전달되는 명령줄 문자열은 cmd.exe 명령으로 파싱되는데, 이는 subprocess가 명령줄 인자를 인코딩하는 관례와 실질적으로 다른 문법이기 때문이에요. 정제되지 않은 arg를 제공하면 인자를 명령으로 파싱할 수 있게 될 수 있어요. 프로세스에 전달되는 명령줄 문자열을 더 잘 제어하려면 첫 번째 arg'exact로 바꿀 수 있는데, 이는 Windows 전용 동작을 발동시켜요: 유일한 arg가 하위 프로세스의 명령줄로 정확히 사용돼요. 비-Windows 플랫폼에서 'exact가 제공되면 exn:fail:contract 예외가 발생해요.

포트로 제공되면 stdout은 실행된 프로세스의 표준 출력에, stdin은 프로세스의 표준 입력에, stderr은 프로세스의 표준 오류에 사용돼요. 제공된 모든 포트는 파일 스트림 포트여야 해요. 포트 중 어느 것이든 #f일 수 있고, 그 경우 시스템 파이프가 만들어져 subprocess가 반환해요. stderr 인자는 'stdout일 수 있고, 그 경우 표준 출력으로 제공된 같은 파일 스트림 포트나 시스템 파이프가 표준 오류에도 사용돼요. 각 제공된 포트 또는 'stdout에 대해 파이프는 만들어지지 않고 대응하는 반환 값은 #f예요. stdout이나 stderrport-waiting-peer?가 참을 반환하는 포트라면, subprocess는 하위 프로세스 생성을 진행하기 전에 포트가 쓰기 준비가 될 때까지 기다려요.

group'new면 새 프로세스가 새 OS 수준 프로세스 그룹으로 만들어져요. 그 경우 subprocess-kill은 그룹 안의 모든 프로세스(하위 프로세스가 만든 추가 프로세스를 포함할 수 있음)를 종료하려 시도해요. 그룹을 만드는 것은 대화형 셸의 작업 제어(job control)를 방해할 수 있다는 점을 조심하세요. 작업 제어는 프로세스 그룹에 기반하거든요. 자세한 내용은 subprocess-kill을 보세요. groupsubprocess라면 그 하위 프로세스는 'new로 만들어졌어야 하고, 새 하위 프로세스가 그 그룹에 추가돼요. 그룹에 추가하는 것은 Unix와 Mac OS에서만, 그리고 subprocess-kill이 효과를 가질 때와 같은 경우에만(즉 하위 프로세스가 종료된 것으로 알려지지 않음) 성공하며, 그렇지 않으면 조용히 실패해요.

subprocess 프로시저는 네 값을 반환해요.

  • 만들어진 프로세스를 나타내는 하위 프로세스 값
  • 프로세스의 표준 출력에서 파이프된 입력 포트, 또는 stdout이 포트였다면 #f
  • 프로세스의 표준 입력으로 파이프된 출력 포트, 또는 stdin이 포트였다면 #f
  • 프로세스의 표준 오류에서 파이프된 입력 포트, 또는 stderr이 포트나 'stdout이었다면 #f

중요: subprocess가 반환한 모든 포트는 보통 close-input-portclose-output-port로 명시적으로 닫아야 해요.

하위 프로세스와 통신하기 위한 파일 스트림 포트는 보통 용량이 제한된 파이프예요. 하위 프로세스에 쓰기 후 읽기를 직렬화하는 동안 하위 프로세스도 같은 일을 해, 양쪽 모두 쓰기에 블록되도록 만드는 교착 상태(deadlock)를 만들지 않도록 조심하세요. 한 쪽이 먼저 읽어 파이프에 공간을 만들어야 하기 때문이에요. 또한 하위 프로세스의 출력을 읽지 않고 하위 프로세스가 끝나기를 기다리지 마세요. 하위 프로세스가 가득 찬 파이프에 출력을 쓰려 하다 블록될 수 있기 때문이에요.

반환된 포트는 파일 스트림 포트(파일 포트 참고)이고, 현재 커스토디언의 관리에 들어가요(커스토디언 참고). 저수준 오류가 프로세스 생성이나 프로세스 통신용 운영 체제 파이프 생성을 막으면 exn:fail 예외가 발생해요.

current-subprocess-custodian-mode 파라미터는 하위 프로세스 자체가 현재 커스토디언에 등록되어, 커스토디언 종료가 하위 프로세스에 대해 subprocess-kill을 호출하는지 결정해요.

current-subprocess-keep-file-descriptors 파라미터는 현재 프로세스의 파일 디스크립터와 핸들이 하위 프로세스와 어떻게 공유되는지 결정해요. stdin, stdout, stderr이 나타내는 파일 디스크립터(Unix와 Mac OS) 또는 핸들(Windows)은 항상 하위 프로세스와 공유돼요. (대응하는 stdin, stdout, stderr 인자가 #f일 때) 새로 만들어진 파이프로 대체되는 파일 디스크립터와 핸들은 공유되지 않아요. 다른 파일 디스크립터와 핸들의 공유는 파라미터 값에 따라 달라져요.

  • 'inherited(기본값) — Windows에서 상속되는 다른 핸들은 하위 프로세스와 공유돼요. FD_CLOEXEC 플래그가 없는 파일 디스크립터는 그 플래그를 지원하는 Unix 및 Mac OS 변종에서 공유돼요. FD_CLOEXEC를 지원하지 않는 Unix 및 Mac OS 변종에서는 그 외 다른 파일 디스크립터는 공유되지 않아요.
  • 'all'inherited와 같지만, FD_CLOEXEC를 지원하지 않는 Unix 및 Mac OS 변종에서는 모든 파일 디스크립터가 공유돼요.
  • '() — Windows에서 상속되거나 FD_CLOEXEC 플래그가 없더라도 추가 파일 디스크립터는 공유되지 않아요.

하위 프로세스는 동기화 가능한 이벤트로 사용될 수 있어요(이벤트 참고). 하위 프로세스 값은 subprocess-wait가 블록되지 않을 때 동기화할 준비가 되고, 하위 프로세스 값의 동기화 결과는 그 하위 프로세스 값 자체예요.

예제:

(define-values (sp out in err)
  (subprocess #f #f #f "/bin/ls" "-l"))
(printf "stdout:\n~a" (port->string out))
(printf "stderr:\n~a" (port->string err))
(close-input-port out)
(close-output-port in)
(close-input-port err)
(subprocess-wait sp)

변경 사항: base 패키지 6.11.0.1 버전에서 group 인자가 추가됐어요. 7.4.0.5 버전에서 리더 없는 fifo를 stdout 및/또는 stderr로 기다리는 것이 추가됐어요. 8.3.0.4 버전에서 current-subprocess-custodian-mode 지원이 추가됐어요. 8.11.1.6 버전에서 FD_CLOEXEC를 지원하는 Unix 및 Mac OS 변종의 파일 디스크립터 공유 처리가 바뀌었어요.

(subprocess-wait subproc) → void?
  subproc : subprocess?

subproc이 나타내는 프로세스가 종료될 때까지 블록돼요. subproc 값은 syncsync/timeout에도 쓸 수 있어요.

(subprocess-status subproc) → (or/c 'running exact-nonnegative-integer?)
  subproc : subprocess?

subproc이 나타내는 프로세스가 여전히 실행 중이면 'running을, 아니면 그 종료 코드를 반환해요. 종료 코드는 정확한 정수이고, 0은 보통 성공을 나타내요. 프로세스가 결함(fault)이나 신호로 종료되면 종료 코드는 0이 아니에요.

(subprocess-kill subproc force?) → void?
  subproc : subprocess?
  force? : any/c

subproc이 나타내는 하위 프로세스를 종료해요. 정확한 동작은 force?가 참인지, 프로세스가 subprocess-group-enabled 파라미터를 참 값으로 설정해 자신의 그룹으로 만들어졌는지, 그리고 현재 플랫폼에 따라 달라져요.

  • force? 참, 그룹 아님, 모든 플랫폼: 프로세스가 여전히 실행 중이면 그 프로세스를 종료해요.
  • force? 거짓, 그룹 아님, Unix 또는 Mac OS: kill 신호 대신 프로세스에 인터럽트 신호를 보내요.
  • force? 거짓, 그룹 아님, Windows: 아무 조치도 취하지 않아요.
  • force? 참, 그룹, Unix 또는 Mac OS: 그룹의 모든 프로세스를 종료해요. 다만 subprocess-status가 그 하위 프로세스에 대해 'running이 아닌 결과를 만든 적이 없고, subprocess-wait이나 sync 같은 함수가 하위 프로세스의 완료를 감지하지 않았을 때만. 그렇지 않으면 아무 조치도 취하지 않아요(즉시 프로세스가 종료된 것으로 알려졌지만 그룹의 지속 존재는 알 수 없으므로).
  • force? 참, 그룹, Windows: 프로세스가 여전히 실행 중이면 그 프로세스를 종료해요.
  • force? 거짓, 그룹, Unix 또는 Mac OS: force?#t일 때와 같지만, 그룹에 신호를 보낼 때 kill 신호 대신 인터럽트 신호예요.
  • force? 거짓, 그룹, Windows: 그룹의 모든 프로세스가 CTRL-BREAK 신호를 받아요(즉시 하위 프로세스가 종료되었는지와 무관하게).

종료 중에 오류가 발생하면 exn:fail 예외가 발생해요.

(subprocess-pid subproc) → exact-nonnegative-integer?
  subproc : subprocess?

subproc이 나타내는 프로세스에 대한 운영 체제의 숫자 ID(있으면)를 반환해요. 결과는 프로세스가 실행 중인 동안에만 유효해요.

(subprocess? v) → boolean?
  v : any/c

v가 하위 프로세스 값이면 #t, 아니면 #f를 반환해요.

(current-subprocess-custodian-mode)
  → (or/c #f 'kill 'interrupt)
(current-subprocess-custodian-mode mode) → void?
  mode : (or/c #f 'kill 'interrupt)

(하위 프로세스나 process 같은 래퍼가 만든) 하위 프로세스가 현재 커스토디언에 등록되는지 결정하는 파라미터예요. 파라미터 값이 #f면 하위 프로세스는 커스토디언에 등록되지 않아요—만들어진 포트는 등록되지만. 값이 'kill이나 'interrupt면 하위 프로세스가 subprocess-kill을 통해 종료되는데, 'killforce? 인자에 #t 값을, 'interrupt#f 값을 제공해요. 종료는 하위 프로세스용으로 만들어진 포트가 닫히기 전이나 후에 발생할 수 있어요.

커스토디언이 발동한 종료는 호스트 시스템의 프로세스 처리 세부 사항에 의해 제한돼요. 예를 들어 processsystem은 프로그램을 실행하기 위해 중간 셸 프로세스를 만들 수 있고, 그 경우 커스토디언 기반 종료는 셸 프로세스를 종료하며 셸이 시작한 프로세스는 아마 종료하지 않아요. subprocess-kill도 함께 보세요. 프로세스 그룹(subprocess-group-enabled 참고)은 일부 제한을 해결할 수 있지만 전부는 아니에요.

(subprocess-group-enabled) → boolean?
(subprocess-group-enabled on?) → void?
  on? : any/c

하위 프로세스가 기본적으로 새 프로세스 그룹으로 만들어지는지 결정하는 파라미터예요. 자세한 정보는 subprocesssubprocess-kill을 보세요.

(current-subprocess-keep-file-descriptors)
  → (or/c 'inherited 'all '())
(current-subprocess-keep-file-descriptors keeps) → void?
  keeps : (or/c 'inherited 'all '())

(하위 프로세스나 process 같은 래퍼가 만든) 하위 프로세스에서 파일 디스크립터(Unix와 Mac OS)와 핸들(Windows)이 어떻게 공유되는지 결정하는 파라미터예요. 자세한 정보는 subprocess를 보세요.

base 패키지 8.3.0.4 버전에서 추가.

(shell-execute verb target parameters dir show-mode) → #f
  verb : (or/c string? #f)
  target : string?
  parameters : string?
  dir : path-string?
  show-mode : symbol?

Windows에서 targetverb가 지정하는 동작을 수행해요. Windows가 아닌 플랫폼에서는 exn:fail:unsupported 예외가 발생해요.

예를 들어

(shell-execute #f "http://racket-lang.org" ""
               (current-directory) 'sw_shownormal)

은 브라우저 창에서 Racket 홈페이지를 열어요.

verb#f일 수 있고, 그 경우 운영 체제가 기본 동사를 사용해요. 흔한 동사로는 "open", "edit", "find", "explore", "print"가 있어요.

target은 동작의 대상으로, 보통 파일 이름 경로예요. 파일은 실행 가능하거나, 설치된 응용 프로그램이 처리할 수 있는 인식된 확장자를 가진 파일일 수 있어요.

parameters 인자는 동작을 수행하도록 시스템에 전달돼요. 예를 들어 실행 파일을 여는 경우 parameters는 (실행 파일 이름 뒤의) 명령줄로 사용돼요.

dir은 동작을 수행할 때 현재 디렉터리로 사용돼요.

show-mode는 동작의 영향을 받는 창의 표시 모드를 설정해요. 다음 심볼 중 하나여야 해요. 각 심볼 의미에 대한 설명은 Windows API 문서에서 가져온 것이에요.

  • 'sw_hide 또는 'SW_HIDE — 창을 숨기고 다른 창을 활성화해요.
  • 'sw_maximize 또는 'SW_MAXIMIZE — 창을 최대화해요.
  • 'sw_minimize 또는 'SW_MINIMIZE — 창을 최소화하고 z-순서에서 다음 최상위 창을 활성화해요.
  • 'sw_restore 또는 'SW_RESTORE — 창을 활성화하고 표시해요. 창이 최소화되거나 최대화되어 있으면 Windows가 창을 원래 크기와 위치로 복원해요.
  • 'sw_show 또는 'SW_SHOW — 창을 활성화하고 현재 크기와 위치로 표시해요.
  • 'sw_showdefault 또는 'SW_SHOWDEFAULT — 기본값을 사용해요.
  • 'sw_showmaximized 또는 'SW_SHOWMAXIMIZED — 창을 활성화하고 최대화된 창으로 표시해요.
  • 'sw_showminimized 또는 'SW_SHOWMINIMIZED — 창을 활성화하고 최소화된 창으로 표시해요.
  • 'sw_showminnoactive 또는 'SW_SHOWMINNOACTIVE — 창을 최소화된 창으로 표시해요. 활성 창은 활성 상태로 남아요.
  • 'sw_showna 또는 'SW_SHOWNA — 창을 현재 상태로 표시해요. 활성 창은 활성 상태로 남아요.
  • 'sw_shownoactivate 또는 'SW_SHOWNOACTIVATE — 창을 가장 최근 크기와 위치로 표시해요. 활성 창은 활성 상태로 남아요.
  • 'sw_shownormal 또는 'SW_SHOWNORMAL — 창을 활성화하고 표시해요. 창이 최소화되거나 최대화되어 있으면 Windows가 창을 원래 크기와 위치로 복원해요.

동작이 실패하면 exn:fail 예외가 발생해요. 동작이 성공하면 결과는 #f예요.

향후 Racket 버전에서, 운영 체제가 프로세스 핸들을 반환하면 결과가 하위 프로세스 값일 수 있어요(하지만 하위 프로세스 값이 반환되면 그 프로세스 ID는 실제 프로세스 ID 대신 0일 거예요).

15.4.1 간단한 하위 프로세스

(require racket/system)  ; package: base

이 섹션에서 다루는 바인딩은 racket/baseracket이 아니라 racket/systemracket 라이브러리가 제공해요.

(system command [#:set-pwd? set-pwd?]) → boolean?
  command : (or/c string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

셸 명령을 동기적으로 실행해요(즉 system 호출은 하위 프로세스가 끝날 때까지 반환하지 않음). Unix와 Mac OS에서 /bin/sh가 셸로 사용되고, Windows에서는 cmd.exe(또는 cmd.exe가 없으면 command.com)가 사용돼요. command 인자는 nul 문자를 포함하지 않는 문자열이나 바이트 문자열이에요. 명령이 성공하면 반환 값은 #t, 아니면 #f예요.

오류 처리와 하위 프로세스 파이프의 제한된 버퍼 용량에 대한 설명은 subprocess도 함께 보세요.

set-pwd?가 참이면 셸 프로세스를 시작할 때 PWD 환경 변수가 (current-directory)의 값으로 설정돼요.

system을 구현하는 데 쓰이는 하위 프로세스에 영향을 주는 current-subprocess-custodian-modesubprocess-group-enabled도 함께 보세요.

결과 프로세스는 (current-output-port)에 쓰고, (current-input-port)에서 읽으며, (current-error-port)에 오류를 기록해요. 예를 들어 프로세스의 비오류 출력을 문자열로 모으려면, 주어진 함수를 호출하는 동안 current-output-port를 설정하는 with-output-to-string을 쓰세요.

(with-output-to-string (lambda () (system "date")))
(system* command arg ... [#:set-pwd? set-pwd?]) → boolean?
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

(system* command exact arg [#:set-pwd? set-pwd?]) → boolean?
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))

system과 같지만, command는 (셸 명령을 통하지 않고 직접 실행되는) 파일 이름이고(PATH 환경 변수에 기반해 실행 파일을 찾으려면 find-executable-path 참고), arg들은 인자예요. 실행된 파일은 지정된 문자열 인자(nul 문자를 포함하면 안 됨)를 전달받아요.

Windows에서 command 뒤의 첫 번째 인자는 'exact일 수 있고, 마지막 arg는 완전한 명령줄이에요. 자세한 내용과 ".bat" 또는 ".cmd" 파일을 가리키는 명령을 쓰는 것에 대한 특정 경고는 subprocess를 보세요.

(system/exit-code command [#:set-pwd? set-pwd?]) → byte?
  command : (or/c string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

system과 같지만, 결과는 하위 프로세스가 반환한 종료 코드예요. 0 결과는 보통 성공을 나타내요.

(system*/exit-code command arg ... [#:set-pwd? set-pwd?]) → byte?
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

(system*/exit-code command exact arg [#:set-pwd? set-pwd?]) → byte?
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))

system*과 같지만, system/exit-code처럼 종료 코드를 반환해요.

(process command [#:set-pwd? set-pwd?])
  → (list input-port? output-port? exact-nonnegative-integer?
          input-port?
          ((or/c 'status 'wait 'interrupt 'kill) . -> . any))
  command : (or/c string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

셸 명령을 비동기적으로 실행해요(Unix와 Mac OS에서 /bin/sh, Windows에서 cmd.exe 또는 command.com 사용). 결과는 다섯 값의 목록이에요.

오류 처리와 하위 프로세스 파이프의 제한된 버퍼 용량에 대한 설명은 subprocess도 함께 보세요.

  • 하위 프로세스의 표준 출력에서 파이프된 입력 포트

  • 하위 프로세스의 표준 입력으로 파이프된 출력 포트

  • 하위 프로세스의 시스템 프로세스 id

  • 하위 프로세스의 표준 오류에서 파이프된 입력 포트

  • 그리고 'status, 'wait, 'interrupt, 'exit-code, 'kill 중 하나인 인자 하나를 받는 프로시저:

    • 'status는 하위 프로세스의 상태를 'running, 'done-ok, 'done-error 중 하나로 반환해요.

    • 'exit-code는 하위 프로세스의 정수 종료 코드를, 여전히 실행 중이면 #f를 반환해요.

    • 'wait는 하위 프로세스가 완료될 때까지 현재 스레드의 실행을 블록해요.

    • 'interrupt는 Unix와 Mac OS에서 하위 프로세스에 인터럽트 신호를 보내고, Windows에서는 아무 동작도 하지 않아요. 결과는 #<void>예요.

      Unix와 Mac OS에서 command가 단일 프로그램을 실행하면, /bin/sh는 보통 그 프로그램이 같은 프로세스에서 /bin/sh를 대체하도록 실행해요. 그러나 프로세스 생성에 대한 신뢰할 수 있고 정밀한 제어를 원한다면 process*을 쓰세요.

    • 'kill은 하위 프로세스를 종료하고 #<void>를 반환해요. process가 만든 즉시 프로세스는 다른 프로그램을 실행할 수 있는 셸 프로세스라는 점을 기억하세요. 셸 프로세스를 종료하는 것은 셸이 시작한 프로세스를 종료하지 않을 수 있어요, 특히 Windows에서.

중요: process가 반환한 세 포트 모두 close-input-portclose-output-port로 명시적으로 닫아야 해요.

set-pwd?가 참이면 system과 같은 방식으로 PWD가 설정돼요.

process를 구현하는 데 쓰이는 하위 프로세스에 영향을 주는 current-subprocess-custodian-modesubprocess-group-enabled도 함께 보세요. 특히 'interrupt'kill 프로세스 제어 메시지는 subprocess-kill로 구현되므로, 단일 프로세스 대신 프로세스 그룹에 영향을 줄 수 있어요.

(process* command arg ... [#:set-pwd? set-pwd?]) → list?
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

(process* command exact arg [#:set-pwd? set-pwd?]) → list?
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))

process와 같지만, commandsystem*처럼 직접 실행되는 파일 이름이고, arg들은 인자예요.

Windows에서 system*처럼 첫 번째 arg'exact로 바꿀 수 있어요. ".bat" 또는 ".cmd" 파일을 가리키는 명령을 쓰는 것에 대한 특정 경고는 subprocess도 함께 보세요.

(process/ports out in error-out command [#:set-pwd? set-pwd?]) → list?
  out : (or/c #f output-port?)
  in : (or/c #f input-port?)
  error-out : (or/c #f output-port? 'stdout)
  command : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

process와 같지만, out은 프로세스의 표준 출력에, in은 프로세스의 표준 입력에, error-out은 프로세스의 표준 오류에 사용돼요. 포트 중 어느 것이든 #f일 수 있고, 그 경우 process에서처럼 시스템 파이프가 만들어져 반환돼요. error-out'stdout이면 표준 오류가 표준 출력으로 리다이렉션돼요. 각 제공된 포트 또는 'stdout에 대해 파이프는 만들어지지 않고, 반환된 목록의 대응하는 값은 #f예요.

(process*/ports out in error-out command arg ... [#:set-pwd? set-pwd?]) → list?
  out : (or/c #f output-port?)
  in : (or/c #f input-port?)
  error-out : (or/c #f output-port? 'stdout)
  command : path-string?
  arg : (or/c path? string-no-nuls? bytes-no-nuls?)
  set-pwd? : any/c = (member (system-type) '(unix macosx))

(process*/ports out in error-out command exact arg [#:set-pwd? set-pwd?]) → list?
  out : (or/c #f output-port?)
  in : (or/c #f input-port?)
  error-out : (or/c #f output-port? 'stdout)
  command : path-string?
  exact : 'exact
  arg : string?
  set-pwd? : any/c = (member (system-type) '(unix macosx))

process*과 같지만, process/ports의 포트 처리를 해요.

system 및 관련 함수들의 계약은 다음 함수들에 대한 참조와 함께 계약 오류를 신호할 수 있어요.

(string-no-nuls? x) → boolean?
  x : any/c

x가 문자열이고 "\u0000"을 포함하지 않음을 보장해요.

(bytes-no-nuls? x) → boolean?
  x : any/c

x가 바이트 문자열이고 #"\0"을 포함하지 않음을 보장해요.

더 알아보기

  • 커스토디언(Custodians)
  • 15.4.1 간단한 하위 프로세스: racket/systemsystem, system*, process, process*
  • 이벤트(Events): 하위 프로세스 동기화