¿Cómo se accede a los argumentos de la línea de comandos para una aplicación de línea de comandos en Swift?
¿Cómo se accede a los argumentos de la línea de comandos para una aplicación de línea de comandos en Swift?
Respuestas:
Apple ha lanzado la ArgumentParser
biblioteca para hacer precisamente esto:
Estamos encantados de anunciar
ArgumentParser
una nueva biblioteca de código abierto que lo hace sencillo, ¡incluso agradable! - para analizar los argumentos de la línea de comandos en Swift.
https://github.com/apple/swift-argument-parser
Comience declarando un tipo que defina la información que necesita recopilar desde la línea de comando. Decore cada propiedad almacenada con uno de
ArgumentParser
los envoltorios de propiedad y declare la conformidad conParsableCommand
.La
ArgumentParser
biblioteca analiza los argumentos de la línea de comandos, crea una instancia de su tipo de comando y luego ejecuta surun()
método personalizado o sale con un mensaje útil.
Actualización 17/01/17: Se actualizó el ejemplo de Swift 3. Process
ha cambiado de nombre CommandLine
.
Actualización 30/09/2015: Se actualizó el ejemplo para que funcione en Swift 2.
De hecho, es posible hacer esto sin Foundation o C_ARGV
y C_ARGC
.
La biblioteca estándar de Swift contiene una estructura CommandLine
que tiene una colección de String
s llamados arguments
. Entonces podrías activar argumentos como este:
for argument in CommandLine.arguments {
switch argument {
case "arg1":
print("first argument")
case "arg2":
print("second argument")
default:
print("an argument")
}
}
Process.arguments
lo mismo que NSProcessInfo.processInfo().arguments
?
Process
objeto ahora se conoce como el CommandLine
objeto. Esto probablemente se incorporará por completo una vez que Swift 3.0 se lance oficialmente.
Utilice las constantes de nivel superior C_ARGC
y 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")
}
}
Tenga en cuenta que estoy usando el rango de 1..C_ARGC
porque el primer elemento de la C_ARGV
"matriz" es la ruta de la aplicación.
La C_ARGV
variable no es en realidad una matriz, sino que es sub-programable como una matriz.
C_ARCG
parece que ya no se admite.
Process.argc
y Process.arguments
para esto, aunque parece que esto podría estar cambiando para CommandLine.argc
y CommandLine.arguments
con los cambios más recientes a la lengua.
Cualquiera que quiera usar el antiguo "getopt" (que está disponible en Swift) puede usarlo como referencia. Hice un puerto Swift del ejemplo de GNU en C que se puede encontrar en:
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
con una descripción completa. Está probado y es completamente funcional. Tampoco requiere Fundación.
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)])!)'")
}
Puede crear un analizador de argumentos utilizando CommandLine.arguments
Array y agregar la lógica que desee.
Puedes probarlo. Crea un archivoarguments.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)
}
compílelo y ejecútelo:
$ swiftc arguments.swift
$ ./arguments argument1 argument2 argument3
El problema con la construcción de su propio analizador de argumentos es tener en cuenta todas las convenciones de argumentos de la línea de comandos. Recomendaría usar un analizador de argumentos existente.
Podrías usar:
He escrito sobre cómo construir herramientas de línea de comandos en los tres. Deberías echarles un vistazo y decidir qué estilo te queda mejor.
Si está interesado aquí están los enlaces: