Wie greifen Sie in Swift auf Befehlszeilenargumente für eine Befehlszeilenanwendung zu?
Wie greifen Sie in Swift auf Befehlszeilenargumente für eine Befehlszeilenanwendung zu?
Antworten:
Apple hat die ArgumentParser
Bibliothek dafür veröffentlicht:
Wir freuen uns, Ihnen
ArgumentParser
eine neue Open-Source-Bibliothek vorstellen zu können , die es unkompliziert macht - und sogar Spaß macht! - um Befehlszeilenargumente in Swift zu analysieren.
https://github.com/apple/swift-argument-parser
Deklarieren Sie zunächst einen Typ, der die Informationen definiert, die Sie über die Befehlszeile erfassen müssen. Dekorieren Sie jede gespeicherte Eigenschaft mit einem der
ArgumentParser
Eigenschafts-Wrapper und erklären Sie die Konformität mitParsableCommand
.Die
ArgumentParser
Bibliothek analysiert die Befehlszeilenargumente, instanziiert Ihren Befehlstyp und führt dann entweder Ihre benutzerdefinierterun()
Methode aus oder beendet sie mit einer nützlichen Nachricht.
Update 17.01.17: Das Beispiel für Swift 3 Process
wurde aktualisiert und in umbenannt CommandLine
.
Update 30.09.2015: Das Beispiel wurde aktualisiert, um in Swift 2 zu funktionieren.
Es ist tatsächlich möglich, dies ohne Foundation oder C_ARGV
und zu tun C_ARGC
.
Die Swift-Standardbibliothek enthält eine Struktur CommandLine
mit einer Sammlung von String
s namens arguments
. Sie können also folgende Argumente aktivieren:
for argument in CommandLine.arguments {
switch argument {
case "arg1":
print("first argument")
case "arg2":
print("second argument")
default:
print("an argument")
}
}
Process.arguments
das gleiche wie NSProcessInfo.processInfo().arguments
?
Process
Objekt jetzt als CommandLine
Objekt bezeichnet. Dies wird wahrscheinlich vollständig integriert sein, sobald Swift 3.0 offiziell veröffentlicht ist.
Verwenden Sie in Swift 3 CommandLine
Enum anstelle vonProcess
So:
let arguments = CommandLine.arguments
Verwenden Sie die Konstanten der obersten Ebene C_ARGC
und 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")
}
}
Beachten Sie, dass ich den Bereich von verwende, 1..C_ARGC
da das erste Element des C_ARGV
"Arrays" der Pfad der Anwendung ist.
Die C_ARGV
Variable ist eigentlich kein Array, kann aber wie ein Array subskriptiert werden.
C_ARCG
scheint nicht mehr unterstützt zu werden.
Process.argc
und Process.arguments
dafür verwenden, obwohl es so aussieht, als würde sich dies zu CommandLine.argc
und CommandLine.arguments
mit den letzten Änderungen an der Sprache ändern.
Jeder, der das alte "getopt" (das in Swift verfügbar ist) verwenden möchte, kann dies als Referenz verwenden. Ich habe einen Swift-Port des GNU-Beispiels in C erstellt, das unter folgender Adresse zu finden ist:
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
mit einer vollständigen Beschreibung. Es ist getestet und voll funktionsfähig. Es erfordert auch keine Foundation.
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)])!)'")
}
Sie können mithilfe des CommandLine.arguments
Arrays einen Argumentparser erstellen und eine beliebige Logik hinzufügen.
Sie können es testen. Erstellen Sie eine Dateiarguments.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)
}
Kompilieren Sie es und führen Sie es aus:
$ swiftc arguments.swift
$ ./arguments argument1 argument2 argument3
Das Problem beim Erstellen eines eigenen Argumentparsers besteht darin, alle Befehlszeilenargumentkonventionen zu berücksichtigen. Ich würde empfehlen, einen vorhandenen Argument-Parser zu verwenden.
Du könntest benutzen:
Ich habe darüber geschrieben, wie man Befehlszeilen-Tools für alle drei erstellt. Sie sollten sie ausprobieren und entscheiden, welcher Stil am besten zu Ihnen passt.
Wenn Sie hier interessiert sind, sind die Links: