How do you access command line arguments in Swift?
Solution 1
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.
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 toParsableCommand
.The
ArgumentParser
library parses the command-line arguments, instantiates your command type, and then either executes your customrun()
method or exits with useful a message.
Solution 2
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 String
s 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")
}
}
Solution 3
In Swift 3 use CommandLine
enum instead of Process
So:
let arguments = CommandLine.arguments
Solution 4
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.
Solution 5
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)])!)'")
}
Comments
-
Anthony Mittaz about 4 years
How do you access command line arguments for a command line application in Swift?
-
Jack Lawrence about 10 yearsYou can also use NSProcessInfo, just like you do in Objective-C.
-
orj about 10 yearsNSProcessInfo requires Foundation. My answer doesn't require Foundation. Just uses swift lang standard lib.
-
Albin Stigo over 9 yearsIf you want an array this construct is quite handy
let args = [String](Process.arguments)
-
Lance over 9 years@AlbinStigo Process.arguments is already an array of strings, no need to make a new one.
-
HepaKKes over 9 yearsAs almost always the best answer is not the the accepted one. :)
-
juandesant almost 9 years
println
has been changed toprint
recently, but indeed this is the best answer. -
juandesant almost 9 years
C_ARCG
seems to no longer be supported. -
robobrobro over 8 yearsIf anyone besides me cares, Process is actually an enumeration.
-
svth over 8 yearsI can confirm that C_ARG no longer works with the latest version of the tools, XCode Version 7.1 (7B91b).
-
Honghao Zhang about 8 yearsUse of unresolved identifier 'C_ARGC', not supported anymore on Xcode 7.3
-
Franklin Yu about 8 yearsIs
Process.arguments
the same asNSProcessInfo.processInfo().arguments
? -
Alonso Urbano almost 8 yearsOperator
..
is not defined for ranges, it's either...
or..<
-
TheSoundDefense almost 8 yearsIn the most recent Swift snapshots (either the 7/28 snapshot or the 7/29 snapshot), the
Process
object is now known as theCommandLine
object. This will probably be fully incorporated once Swift 3.0 is officially released. -
TheSoundDefense almost 8 yearsYou can instead use
Process.argc
andProcess.arguments
for this, though it looks like this might be changing toCommandLine.argc
andCommandLine.arguments
with the most recent changes to the language. -
BTRUE about 7 yearsLook at @marc adams 's answer below, instead of this one.
-
d4Rk over 6 yearsSwift 4:
ProcessInfo().arguments