Spec-Zone.ru › Haskell 7

Система.Процесс

Авторские права (c) Университет Глазго 2004-2008
Лицензия BSD-стиль (см. файл libraries/base/LICENSE)
Поддерживающий libraries@haskell.org
Устойчивость экспериментальная
Переносимость непереносимая (требуется конкурентность)
Безопасный Haskell Безопасный
Язык Haskell2010

Содержание

  • Запуск дочерних процессов
    • Более простые функции для общих задач
    • Связанные утилиты
    • Обработка нажатия клавиши Control-C в Unix
  • Завершение процесса
  • Старые устаревшие функции

Описание

Операции для создания и взаимодействия с дочерними процессами.

Запуск дочерних процессов

createProcess :: CreateProcess -> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle) Исходный код

Это наиболее общий способ запуска внешнего процесса. Процесс может быть командной строкой, которая должна быть выполнена оболочкой, или сырой командой со списком аргументов. Потоки stdin, stdout и stderr нового процесса могут индивидуально быть подключены к новым каналам, к существующим Handle или просто унаследованы от родительского процесса (по умолчанию).

Подробности о создании процесса передаются в записи CreateProcess. Чтобы упростить создание CreateProcess, предоставляются функции proc и shell, которые заполняют поля значениями по умолчанию, которые можно переопределить по мере необходимости.

createProcess возвращает (mb_stdin_hdl, mb_stdout_hdl, mb_stderr_hdl, ph), где

  • если std_in == CreatePipe, то mb_stdin_hdl будет Just h, где h — это выходной конец канала, подключенного к stdin дочернего процесса.
  • в противном случае, mb_stdin_hdl == Nothing

Аналогично для mb_stdout_hdl и mb_stderr_hdl.

Например, чтобы выполнить простую ls команду:

  r <- createProcess (proc "ls" [])

Чтобы создать канал для чтения вывода ls:

  (_, Just hout, _, _) <-
      createProcess (proc "ls" []){ std_out = CreatePipe }

Чтобы также установить каталог для выполнения ls:

  (_, Just hout, _, _) <-
      createProcess (proc "ls" []){ cwd = Just "\home\bob",
                                    std_out = CreatePipe }

Обратите внимание, что Handle предоставленные для std_in, std_out, или std_err через конструктор UseHandle будут закрыты при вызове этой функции. Это не всегда желаемое поведение. В случаях, когда вы хотите оставить Handle открытым после запуска дочернего процесса, используйте createProcess_ вместо этого.

createProcess_ Исходный код

Аргументы

:: String

имя функции (для сообщений об ошибках)

-> CreateProcess
-> IO (Maybe Handle, Maybe Handle, Maybe Handle, ProcessHandle)

Эта функция почти идентична createProcess. Единственные различия:

  • Handle предоставленные через UseHandle не закрываются автоматически.
  • Эта функция принимает дополнительный аргумент String для использования при создании сообщений об ошибках.

Эта функция доступна в модуле System.Process.Internals некоторое время и является частью модуля System.Process с версии 1.2.1.0.

С: 1.2.1.0

shell :: String -> CreateProcess Исходный код

Создайте запись CreateProcess для передачи в createProcess, представляющую команду, которая должна быть передана оболочке.

proc :: FilePath -> [String] -> CreateProcess Исходный код

Создайте запись CreateProcess для передачи в createProcess, представляющую сырую команду с аргументами.

См. RawCommand для точного смысла указанного FilePath.

data CreateProcess Исходный код

Конструкторы

CreateProcess

Поля

cmdspec :: CmdSpec

Исполняемый файл и аргументы или команда оболочки

cwd :: Maybe FilePath

Необязательный путь к каталогу, в котором будет выполняться новый процесс.

env :: Maybe [(String, String)]

Необязательная среда (в противном случае наследуется от текущего процесса).

std_in :: StdStream

Как определить stdin

std_out :: StdStream

Как определить stdout

std_err :: StdStream

Как определить stderr

close_fds :: Bool

Закрыть все дескрипторы файлов, кроме stdin, stdout и stderr в новом процессе (в Windows, работает только если std_in, std_out и std_err — все Inherit)

create_group :: Bool

Создать новую группу процессов

delegate_ctlc :: Bool

Делегировать обработку нажатия клавиши Control-C. Используйте это для интерактивных консольных процессов, чтобы позволить им обрабатывать нажатие клавиши Control-C сами (см. подробности ниже).

В Windows это не оказывает никакого эффекта.

С: 1.2.0.0

data CmdSpec Исходный код

Конструкторы

ShellCommand String

Командная строка для выполнения с помощью оболочки

RawCommand FilePath [String]

Имя исполняемого файла со списком аргументов

Аргумент FilePath задает имя исполняемого файла и интерпретируется в соответствии с политикой платформы по поиску исполняемых файлов. В частности:

  • в системах Unix используются семантика execvp(3), где, если имя файла исполняемого файла не содержит косых черт (/), то переменная среды PATH просматривается на предмет исполняемого файла.
  • в системах Windows используется семантика Win32 CreateProcess. Кратко: если имя файла не содержит пути, то поиск происходит в каталоге родительского исполняемого файла, а затем в текущем каталоге, затем в некоторых стандартных местах и, наконец, в текущем PATH. Расширение .exe добавляется, если в имени файла еще нет расширения. Для получения полной информации см. документацию для API Windows SearchPath.

Реализации

IsString CmdSpec

построить ShellCommand из строкового литерала

С: 1.2.1.0

data StdStream Исходный код

Конструкторы

Inherit

Унаследовать дескриптор от родителя

UseHandle Handle

Использовать предоставленный дескриптор

CreatePipe

Создать новую трубу. Возвращаемый Handle будет использовать кодировку по умолчанию и режим перевода новых строк (точно так же, как и Handle созданные openFile).

data ProcessHandle Source

Более простые функции для распространённых задач

callProcess :: FilePath -> [String] -> IO () Source

Создаёт новый процесс для выполнения указанной команды с заданными аргументами и ждёт его завершения. Если команда возвращает код выхода, отличный от нуля, возникает исключение.

Если в поток, выполняющий callProcess, брошено асинхронное исключение. Виртуальный процесс будет завершён, и callProcess будет ждать (блокироваться), пока процесс не будет завершён.

С версии: 1.2.0.0

callCommand :: String -> IO () Source

Создаёт новый процесс для выполнения указанной оболочной команды. Если команда возвращает код выхода, отличный от нуля, возникает исключение.

Если в поток, выполняющий callCommand, брошено асинхронное исключение. Виртуальный процесс будет завершён, и callCommand будет ждать (блокироваться), пока процесс не будет завершён.

С версии: 1.2.0.0

spawnProcess :: FilePath -> [String] -> IO ProcessHandle Source

Создаёт новый процесс для выполнения указанной сырой команды с заданными аргументами. Он не ждёт завершения программы, а возвращает ProcessHandle.

С версии: 1.2.0.0

spawnCommand :: String -> IO ProcessHandle Source

Создаёт новый процесс для выполнения указанной оболочной команды. Он не ждёт завершения программы, а возвращает ProcessHandle.

С версии: 1.2.0.0

readCreateProcess Source

Аргументы

:: CreateProcess
-> String

стандартный ввод

-> IO String

stdout

readCreateProcess работает точно так же, как и readProcess, за исключением того, что позволяет передать CreateProcess, обеспечивая большую гибкость.

 > readCreateProcess (shell "pwd" { cwd = "/etc/" }) ""
 "/etc\n"

Обратите внимание, что Handle предоставленные для std_in или std_out через запись CreateProcess будут проигнорированы. С версии: 1.2.3.0

readProcess Source

Аргументы

:: FilePath

Имя файла исполняемого файла (см. RawCommand для подробностей)

-> [String]

любые аргументы

-> String

стандартный ввод

-> IO String

stdout

readProcess порождает внешний процесс, строго считывает его стандартный вывод, блокируется до завершения процесса и возвращает строку вывода. Внешний процесс наследует стандартную ошибку.

Если в поток, выполняющий readProcess, брошено асинхронное исключение, виртуальный процесс будет завершён, и readProcess будет ждать (блокироваться), пока процесс не будет завершён.

Вывод возвращается строго, поэтому это не подходит для интерактивных приложений.

Эта функция выбрасывает IOError, если процесс ExitCode отличается от ExitSuccess. Если вместо этого вы хотите получить ExitCode, используйте readProcessWithExitCode.

Пользователи этой функции должны компилировать с -threaded, если они хотят, чтобы другие потоки Haskell продолжали работать во время ожидания результата readProcess.

 > readProcess "date" [] []
 "Thu Feb  7 10:03:39 PST 2008\n"

Аргументы:

  • Команда для выполнения, которая должна быть в $PATH или абсолютным или относительным путём
  • Список отдельных аргументов командной строки для программы
  • Строка, передаваемая на стандартный ввод виртуальному процессу.

readCreateProcessWithExitCode Source

Аргументы

:: CreateProcess
-> String

стандартный ввод

-> IO (ExitCode, String, String)

код выхода, stdout, stderr

readCreateProcessWithExitCode работает точно так же, как readProcessWithExitCode, за исключением того, что позволяет передавать CreateProcess, что обеспечивает большую гибкость.

Обратите внимание, что Handle предоставленные для std_in, std_out, или std_err через запись CreateProcess будут проигнорированы.

С версии: 1.2.3.0

readProcessWithExitCode Source

Аргументы

:: FilePath

Имя файла исполняемого файла (см. RawCommand для подробностей)

-> [String]

любые аргументы

-> String

стандартный ввод

-> IO (ExitCode, String, String)

код выхода, stdout, stderr

readProcessWithExitCode похож на readProcess, но с двумя отличиями:

  • он возвращает ExitCode процесса и не генерирует исключение, если код не ExitSuccess.
  • он считывает и возвращает вывод из стандартного канала ошибок процесса, а не наследует стандартный канал ошибок процесса.

В системах Unix см. waitForProcess для понимания кодов выхода, когда процесс завершился в результате сигнала.

Связанные утилиты

showCommandForUser :: FilePath -> [String] -> String Source

Для данной программы p и аргументов args, showCommandForUser p args возвращает строку, подходящую для вставки в /bin/sh (в системах Unix) или CMD.EXE (в системах Windows).

Обработка Ctrl-C в системах Unix

При работе с интерактивным консольным процессом (например, оболочкой, текстовым редактором в консоли или ghci), обычно требуется, чтобы этот процесс мог обрабатывать прерывания клавиш Ctrl-C по своему усмотрению. Например, в то время как большинство программ просто завершаются при нажатии Ctrl-C, некоторые обрабатывают его особым образом. Для этого используйте параметр delegate_ctlc = True в параметрах CreateProcess.

Подробности:

По умолчанию Ctrl-C сгенерирует сигнал SIGINT, вызвав исключение UserInterrupt в главном потоке Haskell вашей программы, которое, если не обрабатывается специально, приведёт к завершению программы. Обычно именно этого и требуется: упорядоченного завершения программы в ответ на Ctrl-C.

Конечно, когда в консоли запускается другая интерактивная программа, мы хотим, чтобы эта программа обрабатывала Ctl-C. Однако в Unix Ctl-C отправляет SIGINT всем процессам, использующим консоль. Стандартное решение заключается в том, что при запуске интерактивной программы игнорировать SIGINT в родительском процессе и позволить ему обрабатываться в дочернем процессе. Если этот процесс затем завершается из-за сигнала SIGINT, тогда в этот момент обработать это как если бы мы сами получили SIGINT и начать упорядоченную остановку.

Это поведение реализуется createProcess (и waitForProcess / getProcessExitCode) при установке опции delegate_ctlc = True. В частности, сигнал SIGINT будет игнорироваться до тех пор, пока waitForProcess не вернётся (или getProcessExitCode не вернёт результат, отличный от Nothing), поэтому становится особенно важно использовать waitForProcess для каждого созданного процесса.

Кроме того, в режиме delegate_ctlc waitForProcess и getProcessExitCode будут генерировать исключение UserInterrupt, если процесс завершился с ExitFailure (-SIGINT). Обычно вы не захотите перехватывать это исключение, а позволите ему распространиться, обеспечивая нормальную упорядоченную остановку. Следует знать, что исключение UserInterrupt генерируется синхронно в потоке, вызывающем waitForProcess, в то время как обычно SIGINT вызывает генерировать исключение асинхронно в главном потоке.

Для более подробной информации по этой теме см. "Правильная обработка SIGINT/SIGQUIT".

Завершение процесса

waitForProcess :: ProcessHandle -> IO ExitCode Источник

Ожидает завершения указанного процесса и возвращает его код завершения.

Примечание GHC: для вызова waitForProcess без блокирования всех других потоков в системе необходимо скомпилировать программу с -threaded.

(С тех пор: 1.2.0.0) В системах Unix отрицательное значение ExitFailure -signum указывает, что дочерний процесс был завершён сигналом signum. Номера сигналов зависят от платформы, поэтому для проверки конкретного сигнала используйте константы, предоставленные в пакете System.Posix.Signals unix. Примечание: дампы памяти не сообщаются, используйте System.Posix.Process, если вам нужна эта информация.

getProcessExitCode :: ProcessHandle -> IO (Maybe ExitCode) Источник

Это неблокирующая версия waitForProcess. Если процесс всё ещё выполняется, возвращается Nothing. Если процесс завершился, то возвращается Just e, где e — код завершения процесса.

В системах Unix см. waitForProcess для понимания значений кодов завершения, когда процесс завершился в результате сигнала.

terminateProcess :: ProcessHandle -> IO () Источник

Попытка завершить указанный процесс. Эту функцию не следует использовать в обычных условиях — никакие гарантии не даются относительно того, как аккуратно завершается процесс. Для проверки того, завершился ли процесс, используйте getProcessExitCode.

В системах Unix terminateProcess отправляет процессу сигнал SIGTERM. В системах Windows вызывается функция Win32 TerminateProcess, передавая код завершения 1.

Примечание: в Windows, если процесс был командной оболочкой, созданной createProcess с shell, или созданной runCommand или runInteractiveCommand, тогда terminateProcess завершит только оболочку, а не саму команду. В системах Unix оба процесса находятся в группе процессов и будут завершены вместе.

interruptProcessGroupOf Источник

Аргументы

:: ProcessHandle

Процесс в группе процессов

-> IO ()

Отправляет сигнал прерывания в группу процессов заданного процесса.

В системах Unix отправляет группе сигнал SIGINT.

В системах Windows генерирует CTRL_BREAK_EVENT и будет работать только для процессов, созданных с помощью createProcess и установленным флагом create_group.

createPipe :: IO (Handle, Handle) Источник

Создаёт канал для межпроцессного взаимодействия и возвращает пару (readEnd, writeEnd) Handle.

С тех пор: 1.2.1.0

Старые устаревшие функции

Эти функции предшествуют createProcess, которая намного более гибкая.

runProcess Источник

Аргументы

Запускает исходную команду, необязательно указывая Handle для получения stdin, stdout и stderr каналов для нового процесса (в противном случае эти каналы наследуются от текущего процесса).

Все Handle каналы, переданные runProcess, сразу устанавливаются в закрытое состояние.

Примечание: рассмотрите использование более общей функции createProcess вместо runProcess.

runCommand :: String -> IO ProcessHandle Источник

Запускает команду с помощью оболочки.

runInteractiveProcess Источник

Аргументы

Запускает исходную команду и возвращает Handle которые можно использовать для взаимодействия с процессом через его stdin, stdout и stderr соответственно.

Например, для запуска процесса и подачи строки в его stdin:

  (inp,out,err,pid) <- runInteractiveProcess "..."
  forkIO (hPutStr inp str)

Handle каналы изначально находятся в двоичном режиме; если вам необходимо, чтобы они были в текстовом режиме, используйте hSetBinaryMode.

runInteractiveCommand :: String -> IO (Handle, Handle, Handle, ProcessHandle) Source

Выполняет команду с использованием оболочки и возвращает Handle которые могут быть использованы для связи с процессом через его stdin, stdout, и stderr соответственно. Handle по умолчанию в двоичном режиме; если вам нужно, чтобы они были в текстовом режиме, используйте hSetBinaryMode.

system :: String -> IO ExitCode Source

Вычисление system cmd возвращает код завершения, полученный при выполнении операционной системой командной строки cmd.

Это вычисление может завершиться с одной из следующих IOErrorType исключений:

PermissionDenied
У процесса недостаточно привилегий для выполнения операции.
ResourceExhausted
Недостаточно ресурсов для выполнения операции.
UnsupportedOperation
Реализация не поддерживает системные вызовы.

В Windows system передает команду интерпретатору команд Windows (CMD.EXE или COMMAND.COM), поэтому трюки оболочки Unix не сработают.

В системах Unix см. waitForProcess для определения кодов выхода, когда процесс завершился в результате сигнала.

rawSystem :: String -> [String] -> IO ExitCode Source

Вычисление rawSystem cmd args выполняет операционную систему команду cmd таким образом, что в качестве аргументов получает args строки точно так, как они заданы, без каких-либо забавных экранирований или расширений синтаксиса оболочки. Следовательно, она будет более переносимой между операционными системами, чем system.

Коды возврата и возможные ошибки такие же, как у system.

© The University of Glasgow and others
Licensed under a BSD-style license (see top of the page).
https://downloads.haskell.org/~ghc/7.10.3/docs/html/libraries/process-1.2.3.0/System-Process.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API