Como você acessa argumentos de linha de comando para um aplicativo de linha de comando em Swift?
Como você acessa argumentos de linha de comando para um aplicativo de linha de comando em Swift?
Respostas:
A Apple lançou a ArgumentParser
biblioteca para fazer exatamente isso:
Temos o prazer de anunciar
ArgumentParser
, uma nova biblioteca de código aberto que o torna simples - até mesmo agradável! - para analisar argumentos de linha de comando em Swift.
https://github.com/apple/swift-argument-parser
Comece declarando um tipo que define as informações que você precisa coletar da linha de comando. Decore cada propriedade armazenada com um dos
ArgumentParser
wrappers de propriedade de e declare conformidade comParsableCommand
.A
ArgumentParser
biblioteca analisa os argumentos da linha de comando, instancia seu tipo de comando e, em seguida, executa seurun()
método personalizado ou sai com uma mensagem útil.
Atualização 17/01/17: Atualizado o exemplo para Swift 3. Process
foi renomeado para CommandLine
.
Atualização 30/09/2015: Atualizado o exemplo para funcionar no Swift 2.
Na verdade, é possível fazer isso sem Foundation ou C_ARGV
e C_ARGC
.
A biblioteca padrão do Swift contém uma estrutura CommandLine
que possui uma coleção de String
s chamados arguments
. Portanto, você pode ativar 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
o mesmo que NSProcessInfo.processInfo().arguments
?
Process
objeto agora é conhecido como o CommandLine
objeto. Isso provavelmente será totalmente incorporado quando o Swift 3.0 for oficialmente lançado.
Use as constantes de nível superior C_ARGC
e 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")
}
}
Observe que estou usando o intervalo de 1..C_ARGC
porque o primeiro elemento da C_ARGV
"matriz" é o caminho do aplicativo.
A C_ARGV
variável não é realmente uma matriz, mas pode ser submetida a scripts como uma matriz.
C_ARCG
parece não ser mais compatível.
Process.argc
e Process.arguments
para isso, embora pareça que isso possa estar mudando para CommandLine.argc
e CommandLine.arguments
com as alterações mais recentes do idioma.
Quem quiser usar o antigo "getopt" (que está disponível no Swift) pode usá-lo como referência. Fiz um porte Swift do exemplo GNU em C que pode ser encontrado em:
http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html
com uma descrição completa. É testado e totalmente funcional. Também não requer Fundação.
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)])!)'")
}
Você pode criar um analisador de argumento usando o CommandLine.arguments
Array e adicionar qualquer lógica que desejar.
Você pode testar. Crie um arquivoarguments.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 e execute:
$ swiftc arguments.swift
$ ./arguments argument1 argument2 argument3
O problema de você construir seu próprio analisador de argumento é levar em consideração todas as convenções de argumento da linha de comando. Eu recomendaria usar um Argument Parser existente.
Você pode usar:
Eu escrevi sobre como construir ferramentas de linha de comando em todos os três. Você deve verificá-los e decidir qual estilo se adapta melhor a você.
Se você estiver interessado, aqui estão os links: