146

How do you access command line arguments for a command line application in Swift?

Anthony Mittaz
  • 1,541
  • 2
  • 10
  • 7
  • 2
    Possible duplicate of [How do I access program arguments in Swift?](http://stackoverflow.com/questions/24009050/how-do-i-access-program-arguments-in-swift) – Cœur Apr 17 '17 at 05:56

6 Answers6

324

Update 01/17/17: Updated the example for Swift 3. Process has been renamed to CommandLine.


Update 09/30/2015: Updated the example to work in Swift 2.


It's actually possible to do this without Foundation or C_ARGV and C_ARGC.

The Swift standard library contains a struct CommandLine which has a collection of Strings called arguments. So you could switch on arguments like this:

for argument in CommandLine.arguments {
    switch argument {
    case "arg1":
        print("first argument")

    case "arg2":
        print("second argument")

    default:
        print("an argument")
    }
}
CodeBender
  • 35,668
  • 12
  • 125
  • 132
Mark Adams
  • 30,776
  • 11
  • 77
  • 77
  • If you want an array this construct is quite handy ```let args = [String](Process.arguments)``` – Albin Stigo Jan 05 '15 at 18:11
  • 11
    @AlbinStigo Process.arguments is already an array of strings, no need to make a new one. – Lance Mar 03 '15 at 19:03
  • 10
    As almost always the best answer is not the the accepted one. :) – HepaKKes Mar 31 '15 at 16:05
  • `println` has been changed to `print` recently, but indeed this is the best answer. – juandesant Sep 29 '15 at 08:44
  • 5
    If anyone besides me cares, Process is actually an [enumeration](https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_Process_Enumeration/index.html). – robobrobro Dec 08 '15 at 17:42
  • 1
    Is `Process.arguments` the same as `NSProcessInfo.processInfo().arguments`? – Franklin Yu Jun 07 '16 at 07:07
  • 5
    In the most recent Swift snapshots (either the 7/28 snapshot or the 7/29 snapshot), the `Process` object is now known as the `CommandLine` object. This will probably be fully incorporated once Swift 3.0 is officially released. – TheSoundDefense Aug 08 '16 at 16:50
  • Swift 4: `ProcessInfo().arguments` – d4Rk Mar 29 '18 at 08:23
  • This example code makes no sense. Accessing CommandLine.arguments gives you an array of string, and the number of arguments is the array.count. As always, argument 0 is always present and is the name of the app. – w0mbat May 12 '23 at 20:48
67

In Swift 3 use CommandLine enum instead of Process

So:

let arguments = CommandLine.arguments
Maciek Czarnik
  • 5,950
  • 2
  • 37
  • 50
47

Use the top level constants C_ARGC and C_ARGV.

for i in 1..C_ARGC {
    let index = Int(i);

    let arg = String.fromCString(C_ARGV[index])
    switch arg {
    case "this":
        println("this yo");

    case "that":
        println("that yo")

    default:
        println("dunno bro")
    }
}

Note that I'm using the range of 1..C_ARGC because the first element of the C_ARGV "array" is the application's path.

The C_ARGV variable is not actually an array but is sub-scriptable like an array.

sudo make install
  • 5,629
  • 3
  • 36
  • 48
orj
  • 13,234
  • 14
  • 63
  • 73
15

Apple has released the ArgumentParser library for doing just this:

We’re delighted to announce ArgumentParser, a new open-source library that makes it straightforward — even enjoyable! — to parse command-line arguments in Swift.

https://swift.org/blog/argument-parser/


Swift Argument Parser

https://github.com/apple/swift-argument-parser

Begin by declaring a type that defines the information you need to collect from the command line. Decorate each stored property with one of ArgumentParser's property wrappers, and declare conformance to ParsableCommand.

The ArgumentParser library parses the command-line arguments, instantiates your command type, and then either executes your custom run() method or exits with useful a message.

Community
  • 1
  • 1
pkamb
  • 33,281
  • 23
  • 160
  • 191
14

Anyone who wants to use the old "getopt" (which is available in Swift) can use this as reference. I made a Swift port of the GNU example in C one can find at:

http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html

with a full description. It's tested and fully functional. It doesn't require Foundation either.

var aFlag   = 0
var bFlag   = 0
var cValue  = String()

let pattern = "abc:"
var buffer = Array(pattern.utf8).map { Int8($0) }

while  true {
    let option = Int(getopt(C_ARGC, C_ARGV, buffer))
    if option == -1 {
        break
    }
    switch "\(UnicodeScalar(option))"
    {
    case "a":
        aFlag = 1
        println("Option -a")
    case "b":
        bFlag = 1
        println("Option -b")
    case "c":
        cValue = String.fromCString(optarg)!
        println("Option -c \(cValue)")
    case "?":
        let charOption = "\(UnicodeScalar(Int(optopt)))"
        if charOption == "c" {
            println("Option '\(charOption)' requires an argument.")
        } else {
            println("Unknown option '\(charOption)'.")
        }
        exit(1)
    default:
        abort()
    }
}
println("aflag ='\(aFlag)', bflag = '\(bFlag)' cvalue = '\(cValue)'")

for index in optind..<C_ARGC {
    println("Non-option argument '\(String.fromCString(C_ARGV[Int(index)])!)'")
}
Michele Dall'Agata
  • 1,474
  • 2
  • 15
  • 25
10

You could create an argument parser by using the CommandLine.arguments Array and add any logic you like.

You can test it. Create a file arguments.swift

//Remember the first argument is the name of the executable
print("you passed \(CommandLine.arguments.count - 1) argument(s)")
print("And they are")
for argument in CommandLine.arguments {
    print(argument)
}

compile it and run it:

$ swiftc arguments.swift
$ ./arguments argument1 argument2 argument3

The issue with you building your own argument parser is taking into account all the command-line argument conventions. I would recommend using an existing Argument Parser.

You could use:

  • Vapor's Console module
  • TSCUtility Argument Parser used by the Swift Package manager
  • The Swift Argument Parser open-sourced by Apple

I've written about how to build command-line tools on all three. You should check them out and decide what style suits you best.

If you are interested here are the links:

rderik
  • 460
  • 5
  • 18