How to use Swift for shell scripting

To be honest I’m not very good at shell scripting. It’s very useful for automation so I would like to be, but I just don’t like the syntax. For instance, this is how you check if a variable is greater than 100:

And here’s how to check if the file referred to in the first argument is readable and not empty:

Enough said.

So I would much rather use Swift, as the syntax is nice, very nice indeed. But the things that bash shell scripts actually are good at, like running shell commands and accessing the shell environment, are not that straightforward in Swift. Here’s how you can perform the various tasks using only the Swift Standard Library and Foundation:

Run shell commands

NSTask (Apple, is actually an excellent API which launches asynchronous external processes and has customisable environment, input and outputs. But it definitely needs some helper functions to make it easier to use.

There is also the system function (which has been deprecated) and posix_spawn which is a C API with lots of inout parameters. Again; enough said.

Read input and provide output

Swift’s readLine function reads standard input line by line. And print (previously known as println) prints to standard output.

For more direct control, like seeking and reading and writing binary data, you can use file handles:

Use environment variables

Access arguments

The first element is discarded because it, as is the custom in shell scripting, contains the path to the script file itself.

Read and write files

Or preferably:

readSome takes whatever text is available in the file handle and returns it, whereas read waits for the file handle to be closed and then returns all its contents. If the file handle is never closed it never returns.

Most of the code here is from SwiftShell, a library which makes shell scripting in Swift much simpler.