This post is mostly a brain dump of what it takes to use Swift for command line scripting.
Update: I've added
env. This makes things compatible with recent versions of FreeBSD. There doesn't appear to be a portable solution for Linux because it treats the entire line after the first space as a single argument rather than splitting into multiple arguments and its version of
env doesn't support
#!/usr/bin/env -S xcrun --toolchain <X> swift
The first step is to decide which version of Swift you want to use. Replace
<X> with the toolchain identifier from
com.apple.dt.toolchain.Swift_2_3 - this is the toolchain you get if you don't specify a toolchain or use
/usr/bin/swift directly (when executing Swift scripts on macOS Sierra or earlier)
com.apple.dt.toolchain.XcodeDefault - this is the toolchain you get if you specify an invalid toolchain identifier.
If in doubt, consult this handy table:
I wish you could specify the specific Swift version you wanted instead (rdar://problem/28409078)
You can also pass options to Swift this way:
#!/usr/bin/env -S xcrun --toolchain <X> swift -F/my/frameworks -framework MyUtils.framework -D FLAG
This works just like invoking the compiler or REPL.
-F adds a framework search path.
-framework adds a framework to load.
-D adds a conditional compilation flag.
If you have a collection of personal utilities you'd like to use from scripts just build a framework, drop it somewhere like
/usr/local/lib, and specify the path and framework name in your script.
If you'd prefer something more automated, check out cato which handles picking a Swift version, uses Cocoapods to download frameworks, builds them, and invokes your script with Swift.
Args and Misc
In Swift 3 use
CommandLine.arguments. Index zero is the command itself (in this case your script).
Remember you still need to
import <framework>, including
Process to launch other commands. You can hook its standard input/output up to a
Pipe if you want to capture the output.
Are you writing scripts in Swift? Have any tips or tricks? Please leave a comment!
This blog represents my own personal opinion and is not endorsed by my employer.