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 ArgumentParserBibliothek dafür veröffentlicht:
Wir freuen uns, Ihnen
ArgumentParsereine 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
ArgumentParserEigenschafts-Wrapper und erklären Sie die Konformität mitParsableCommand.Die
ArgumentParserBibliothek 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 Processwurde 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 CommandLinemit einer Sammlung von Strings 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.argumentsdas gleiche wie NSProcessInfo.processInfo().arguments?
ProcessObjekt jetzt als CommandLineObjekt bezeichnet. Dies wird wahrscheinlich vollständig integriert sein, sobald Swift 3.0 offiziell veröffentlicht ist.
Verwenden Sie in Swift 3 CommandLineEnum anstelle vonProcess
So:
let arguments = CommandLine.arguments
Verwenden Sie die Konstanten der obersten Ebene C_ARGCund 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_ARGCda das erste Element des C_ARGV"Arrays" der Pfad der Anwendung ist.
Die C_ARGVVariable ist eigentlich kein Array, kann aber wie ein Array subskriptiert werden.
C_ARCGscheint nicht mehr unterstützt zu werden.
Process.argcund Process.argumentsdafür verwenden, obwohl es so aussieht, als würde sich dies zu CommandLine.argcund CommandLine.argumentsmit 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.argumentsArrays 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: