Swift'de komut satırı argümanlarına nasıl erişirsiniz?


Yanıtlar:


7

Apple, ArgumentParseryalnızca bunu yapmak için kitaplığı yayınladı :

ArgumentParserBunu basit, hatta eğlenceli hale getiren yeni bir açık kaynak kitaplığını duyurmaktan mutluluk duyuyoruz ! - Swift'deki komut satırı argümanlarını ayrıştırmak için.

https://swift.org/blog/argument-parser/


Swift Argüman Ayrıştırıcı

https://github.com/apple/swift-argument-parser

Komut satırından toplamanız gereken bilgileri tanımlayan bir tür bildirerek başlayın. Depolanan her bir ArgumentParsermülkü, ürününün özellik sarmalayıcılarından biriyle dekore edin ve uygunluğunu beyan edin ParsableCommand.

ArgumentParserKütüphane, komut satırı bağımsız değişkenleri ayrıştırır komut tipi başlatır ve sonra ya özel yürütür run()yararlı olan bir mesaj ile bir yöntem ya da çıkış.


305

Güncelleme 01/17/17: Swift 3 için örnek güncellendi. OlarakProcess yeniden adlandırıldı CommandLine.


30.09.2015 Güncellemesi: Örnek, Swift 2'de çalışacak şekilde güncellendi .


Bunu Foundation veya C_ARGV ve olmadan yapmak aslında mümkündür C_ARGC.

Swift standart kitaplığı, adı verilen CommandLinebir koleksiyona sahip bir yapı içerir . Böylece aşağıdaki gibi argümanları açabilirsiniz:Stringarguments

for argument in CommandLine.arguments {
    switch argument {
    case "arg1":
        print("first argument")

    case "arg2":
        print("second argument")

    default:
        print("an argument")
    }
}

10
@AlbinStigo Process.arguments zaten bir dizi dizedir, yenisini yapmaya gerek yoktur.
Lance

9
Neredeyse her zaman olduğu gibi, en iyi cevap kabul edilen cevap değildir. :)
HepaKKes

5
Benden başka biri umursuyorsa, Süreç aslında bir numaralandırmadır .
robobrobro

1
İle Process.argumentsaynı mı NSProcessInfo.processInfo().arguments?
Franklin Yu

5
En son Swift anlık görüntülerinde (7/28 anlık görüntü veya 7/29 anlık görüntü), Processnesne artık nesne olarak bilinir CommandLine. Swift 3.0 resmi olarak piyasaya sürüldüğünde bu muhtemelen tamamen dahil edilecek.
TheSoundDefense


46

Üst düzey sabitleri C_ARGCve 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")
    }
}

"Dizi" nin 1..C_ARGCilk öğesi C_ARGVuygulamanın yolu olduğu için aralığını kullandığıma dikkat edin .

C_ARGVDeğişken aslında bir dizi değil ama alt script bir dizi gibi.


4
Tıpkı Objective-C'de yaptığınız gibi NSProcessInfo'yu da kullanabilirsiniz.
Jack Lawrence

3
NSProcessInfo, Foundation gerektirir. Cevabım Temel gerektirmiyor. Sadece hızlı lang standart lib kullanır.
orj

7
C_ARCGartık desteklenmiyor gibi görünüyor.
juandesant

2
C_ARG'nin artık araçların en son sürümü olan XCode Sürüm 7.1 (7B91b) ile çalışmadığını doğrulayabilirim.
svth

8
Bunun yerine kullanabilirsiniz Process.argcve Process.argumentsbu gibi görünüyor olsa bunun için, değişen olabilir CommandLine.argcve CommandLine.argumentsbu dil için en son değişikliklerle.
TheSoundDefense

14

(Swift'de bulunan) eski "getopt" u kullanmak isteyen herkes bunu referans olarak kullanabilir. C'deki GNU örneğinin bir Swift portunu şu adreste bulabilirim:

http://www.gnu.org/software/libc/manual/html_node/Example-of-Getopt.html

tam bir açıklama ile. Test edildi ve tamamen işlevsel. Foundation da gerektirmez.

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)])!)'")
}

0

Array'i kullanarak bir argüman ayrıştırıcısı oluşturabilir CommandLine.argumentsve istediğiniz herhangi bir mantığı ekleyebilirsiniz.

Test edebilirsiniz. Bir dosya oluşturarguments.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)
}

derleyin ve çalıştırın:

$ swiftc arguments.swift
$ ./arguments argument1 argument2 argument3

Kendi bağımsız değişken çözümleyicinizi oluştururken yaşadığınız sorun, tüm komut satırı bağımsız değişken kurallarını hesaba katmaktır. Mevcut bir Argüman Ayrıştırıcı kullanmanızı tavsiye ederim.

Kullanabilirsin:

  • Vapor'un Konsol modülü
  • Swift Paket yöneticisi tarafından kullanılan TSCUtility Argument Parser
  • Swift Argument Parser, Apple tarafından açık kaynaklı

Üçünde de komut satırı araçlarının nasıl oluşturulacağı hakkında yazdım. Onları kontrol etmeli ve hangi tarzın size en uygun olduğuna karar vermelisiniz.

Eğer ilgileniyorsanız, buradaki bağlantılar:

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.