Làm cách nào để truy cập các đối số dòng lệnh trong Swift?


Câu trả lời:


7

Apple đã phát hành ArgumentParserthư viện để làm điều này:

Chúng tôi rất vui mừng được thông báo ArgumentParser, một thư viện mã nguồn mở mới làm cho nó trở nên đơn giản - thậm chí thú vị! - để phân tích cú pháp các đối số dòng lệnh trong Swift.

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


Swift Argument Parser

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

Bắt đầu bằng cách khai báo một kiểu xác định thông tin bạn cần thu thập từ dòng lệnh. Trang trí từng thuộc tính được lưu trữ bằng một trong ArgumentParsercác trình bao bọc thuộc tính và tuyên bố sự tuân thủ ParsableCommand.

Các ArgumentParserthư viện phân tích các đối số dòng lệnh, instantiates loại lệnh của bạn, và sau đó, hoặc thực hiện tùy chỉnh của bạn run()phương pháp hay lối ra với thông điệp một hữu ích.


305

Cập nhật 17/01/17: Đã cập nhật ví dụ cho Swift 3. Processđã được đổi tên thành CommandLine.


Cập nhật 30/09/2015: Đã cập nhật ví dụ để hoạt động trong Swift 2.


Thực sự có thể làm điều này mà không cần Foundation hoặc C_ARGVC_ARGC.

Thư viện chuẩn của Swift chứa một cấu trúc CommandLinecó một tập hợp các Stringđược gọi arguments. Vì vậy, bạn có thể bật các đối số như sau:

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 đã là một mảng chuỗi, không cần tạo chuỗi mới.
Lance

9
Như hầu hết mọi khi câu trả lời tốt nhất không phải là câu được chấp nhận. :)
HepaKKes

5
Nếu có ai ngoài tôi quan tâm, Process thực sự là một bảng liệt kê .
robobrobro

1
Process.argumentsgiống với NSProcessInfo.processInfo().arguments?
Franklin Yu

5
Trong các ảnh chụp nhanh Swift gần đây nhất (ảnh chụp nhanh 7/28 hoặc ảnh chụp nhanh 7/29), Processđối tượng hiện được gọi là CommandLineđối tượng. Điều này có thể sẽ được kết hợp đầy đủ khi Swift 3.0 chính thức được phát hành.
TheSoundDefense


46

Sử dụng các hằng số cấp cao nhất C_ARGCC_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")
    }
}

Lưu ý rằng tôi đang sử dụng phạm vi 1..C_ARGCvì phần tử đầu tiên của C_ARGV"mảng" là đường dẫn của ứng dụng.

Các C_ARGVbiến không phải là thực sự là một mảng nhưng là tiểu kịch bản như một mảng.


4
Bạn cũng có thể sử dụng NSProcessInfo, giống như bạn làm trong Objective-C.
Jack Lawrence

3
NSProcessInfo yêu cầu Foundation. Câu trả lời của tôi không yêu cầu Foundation. Chỉ cần sử dụng yến lang chuẩn lib.
orj

7
C_ARCGdường như không còn được hỗ trợ.
juandesant

2
Tôi có thể xác nhận rằng C_ARG không còn hoạt động với phiên bản mới nhất của công cụ, XCode Phiên bản 7.1 (7B91b).
svth

8
Thay vào đó, bạn có thể sử dụng Process.argcProcess.argumentscho điều này, mặc dù có vẻ như điều này có thể thay đổi theo CommandLine.argcCommandLine.argumentsvới những thay đổi gần đây nhất đối với ngôn ngữ.
TheSoundDefense

14

Bất kỳ ai muốn sử dụng "getopt" cũ (có sẵn trong Swift) đều có thể sử dụng nó làm tài liệu tham khảo. Tôi đã tạo một cổng Swift của ví dụ GNU trong C, bạn có thể tìm thấy tại:

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

với một mô tả đầy đủ. Nó đã được thử nghiệm và đầy đủ chức năng. Nó cũng không yêu cầu 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)])!)'")
}

0

Bạn có thể tạo một trình phân tích cú pháp đối số bằng cách sử dụng CommandLine.argumentsMảng và thêm bất kỳ logic nào bạn thích.

Bạn có thể kiểm tra nó. Tạo một tệparguments.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)
}

biên dịch nó và chạy nó:

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

Vấn đề với việc bạn xây dựng trình phân tích cú pháp đối số của riêng mình là tính đến tất cả các quy ước đối số dòng lệnh. Tôi khuyên bạn nên sử dụng Trình phân tích cú pháp đối số hiện có.

Bạn đã có thể sử dụng:

  • Mô-đun điều khiển của Vapor
  • Bộ phân tích cú pháp đối số TSCUtility được trình quản lý gói Swift sử dụng
  • Swift Argument Parser do Apple cung cấp nguồn mở

Tôi đã viết về cách xây dựng các công cụ dòng lệnh trên cả ba. Bạn nên kiểm tra chúng và quyết định phong cách phù hợp với bạn nhất.

Nếu bạn quan tâm đây là các liên kết:

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.