Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Subprocess is a cross-platform package for spawning processes in Swift.

License

NotificationsYou must be signed in to change notification settings

swiftlang/swift-subprocess

Subprocess

Subprocess is a cross-platform package for spawning processes in Swift.

Getting Started

To useSubprocess in aSwiftPM project, add it as a package dependency to yourPackage.swift:

dependencies:[.package(url:"https://github.com/swiftlang/swift-subprocess.git", branch:"main")]

Then, adding theSubprocess module to your target dependencies:

.target(    name:"MyTarget",    dependencies:[.product(name:"Subprocess",package:"swift-subprocess")])

Subprocess offers twopackage traits:

  • SubprocessFoundation: includes a dependency onFoundation and adds extensions on Foundation types likeData. This trait is enabled by default.
  • SubprocessSpan: makes Subprocess’ API, mainlyOutputProtocol,RawSpan based. This trait is enabled wheneverRawSpan is available and should only be disabled whenRawSpan is not available.

Please find the API proposalhere.

Swift Versions

The minimal supported Swift version isSwift 6.1.

To experiment with theSubprocessSpan trait, Swift 6.2 is required. Currently, you can download the Swift 6.2 toolchain (main development snapshot)here.

Feature Overview

Run and Asynchonously Collect Output

The easiest way to spawn a process withSubprocess is to simply run it and await itsCollectedResult:

import Subprocessletresult=tryawaitrun(.name("ls"))print(result.processIdentifier) // prints 1234print(result.terminationStatus) // prints exited(0)print(result.standardOutput) // prints LICENSE Package.swift ...

Run with Custom Closure

To have more precise control over input and output, you can provide a custom closure that executes while the child process is active. Inside this closure, you have the ability to manage the subprocess’s state (like suspending or terminating it) and stream its standard output and standard error as anAsyncSequence:

import Subprocess// Monitor Nginx log via `tail -f`asyncletmonitorResult=run(.path("/usr/bin/tail"),    arguments:["-f","/path/to/nginx.log"]){ execution, standardOutputinfortryawaitlinein standardOutput.lines(encoding:UTF8.self){        // Parse the log textif line.contains("500"){            // Oh no, 500 error}}}

Running Unmonitored Processes

WhileSubprocess is designed with Swift’s structural concurrency in mind, it also provides a lower level, synchronous method for launching child processes. However, sinceSubprocess can’t synchronously monitor child process’s state or handle cleanup, you’ll need to attach a FileDescriptor to each I/O directly. Remember to close theFileDescriptor once you’re finished.

import Subprocessletinput:FileDescriptor=...input.closeAfter{letpid=tryrunDetached(.path("/bin/daemon"), input: input)    // ... other opeartions}

Customizable Execution

You can set various parameters when running the child process, such asArguments,Environment, and working directory:

import Subprocessletresult=tryawaitrun(.path("/bin/ls"),    arguments:["-a"],    // Inherit the environment values from parent process and    // add `NewKey=NewValue`     environment:.inherit.updating(["NewKey":"NewValue"]),    workingDirectory:"/Users/",)

Platform Specific Options and “Escape Hatches”

Subprocess providesplatform-specific configuration options, like settinguid andgid on Unix and adjusting window style on Windows, through thePlatformOptions struct. Check out thePlatformOptions documentation for a complete list of configurable parameters across different platforms.

PlatformOptions also allows access to platform-specific spawning constructs and customizations via a closure.

import Darwinimport SubprocessvarplatformOptions=PlatformOptions()letintendedWorkingDir="/path/to/directory"platformOptions.preSpawnProcessConfigurator={ spawnAttr, fileAttrin    // Set POSIX_SPAWN_SETSID flag, which implies calls    // to setsidvarflags:Int16=0posix_spawnattr_getflags(&spawnAttr,&flags)posix_spawnattr_setflags(&spawnAttr, flags |Int16(POSIX_SPAWN_SETSID))    // Change the working directory    intendedWorkingDir.withCString{ pathin        _=posix_spawn_file_actions_addchdir_np(&fileAttr, path)}}letresult=tryawaitrun(.path("/bin/exe"), platformOptions: platformOptions)

Flexible Input and Output Configurations

By default,Subprocess:

  • Doesn’t send any input to the child process’s standard input
  • Captures the child process’s standard output as aString, up to 128kB
  • Ignores the child process’s standard error

You can tailor howSubprocess handles the standard input, standard output, and standard error by setting theinput,output, anderror parameters:

letcontent="Hello Subprocess"// Send "Hello Subprocess" to the standard input of `cat`letresult=tryawaitrun(.name("cat"), input:.string(content, using:UTF8.self))// Collect both standard error and standard output as Dataletresult=tryawaitrun(.name("cat"), output:.data, error:.data)

Subprocess supports these input options:

NoInput

This option means no input is sent to the subprocess.

Use it by setting.none forinput.

FileDescriptorInput

This option reads input from a specifiedFileDescriptor. IfcloseAfterSpawningProcess is set totrue, the subprocess will close the file descriptor after spawning. Iffalse, you are responsible for closing it, even if the subprocess fails to spawn.

Use it by setting.fileDescriptor(closeAfterSpawningProcess:) forinput.

StringInput

This option reads input from a type conforming toStringProtocol using the specified encoding.

Use it by setting.string(using:) forinput.

ArrayInput

This option reads input from an array ofUInt8.

Use it by setting.array forinput.

DataInput (available withSubprocessFoundation trait)

This option reads input from a givenData.

Use it by setting.data forinput.

DataSequenceInput (available withSubprocessFoundation trait)

This option reads input from a sequence ofData.

Use it by setting.sequence forinput.

DataAsyncSequenceInput (available withSubprocessFoundation trait)

This option reads input from an async sequence ofData.

Use it by setting.asyncSequence forinput.


Subprocess also supports these output options:

DiscardedOutput

This option means theSubprocess won’t collect or redirect output from the child process.

Use it by setting.discarded foroutput orerror.

FileDescriptorOutput

This option writes output to a specifiedFileDescriptor. You can choose to have theSubprocess close the file descriptor after spawning.

Use it by setting.fileDescriptor(closeAfterSpawningProcess:) foroutput orerror.

StringOutput

This option collects output as aString with the given encoding.

Use it by setting.string or.string(limit:encoding:) foroutput orerror.

BytesOutput

This option collects output as[UInt8].

Use it by setting.bytes or.bytes(limit:) foroutput orerror.

Cross-platform support

Subprocess works on macOS, Linux, and Windows, with feature parity on all platforms as well as platform-specific options for each.

The table below describes the current level of support that Subprocess has for various platforms:

PlatformSupport Status
macOSSupported
iOSNot supported
watchOSNot supported
tvOSNot supported
visionOSNot supported
Ubuntu 22.04Supported
WindowsSupported

(back to top)

Documentation

The latest API documentation can be viewed by running the following command:

swift package --disable-sandbox preview-documentation --target Subprocess

(back to top)

Contributing to Subprocess

Subprocess is part of the Foundation project. Discussion and evolution take place onSwift Foundation Forum.

If you find something that looks like a bug, please open aBug Report! Fill out as many details as you can.

(back to top)

Code of Conduct

Like all Swift.org projects, we would like the Subprocess project to foster a diverse and friendly community. We expect contributors to adhere to theSwift.org Code of Conduct.

(back to top)

Contact information

The Foundation Workgroup communicates with the broader Swift community using theforum for general discussions.

The workgroup can also be contacted privately by messaging@foundation-workgroup on the Swift Forums.

(back to top)

About

Subprocess is a cross-platform package for spawning processes in Swift.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp