【问题标题】:How do you access command line arguments in Swift?如何在 Swift 中访问命令行参数?
【发布时间】:2014-07-24 15:25:36
【问题描述】:

如何在 Swift 中访问命令行应用程序的命令行参数?

【问题讨论】:

标签: macos command-line-arguments swift


【解决方案1】:

2017 年 1 月 17 日更新:更新了 Swift 3 的示例。Process 已重命名为 CommandLine


2015 年 9 月 30 日更新:更新了示例以在 Swift 2 中工作。


实际上可以在没有 Foundation C_ARGVC_ARGC 的情况下做到这一点。

Swift 标准库包含一个结构 CommandLine,它有一个名为 argumentsStrings 集合。所以你可以像这样打开参数:

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

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

    default:
        print("an argument")
    }
}

【讨论】:

  • @AlbinStigo Process.arguments 已经是一个字符串数组,不需要创建一个新的。
  • 几乎总是最好的答案不是公认的答案。 :)
  • 如果除了我之外还有人关心,Process 实际上是一个enumeration
  • Process.argumentsNSProcessInfo.processInfo().arguments一样吗?
  • 在最近的 Swift 快照(7/28 快照或 7/29 快照)中,Process 对象现在称为CommandLine 对象。一旦 Swift 3.0 正式发布,这可能会被完全纳入。
【解决方案2】:

在 Swift 3 中使用 CommandLine 枚举而不是 Process

所以:

let arguments = CommandLine.arguments

【讨论】:

    【解决方案3】:

    使用顶级常量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")
        }
    }
    

    请注意,我使用的是1..C_ARGC 的范围,因为C_ARGV“数组”的第一个元素是应用程序的路径。

    C_ARGV 变量实际上不是数组,而是像数组一样可下标。

    【讨论】:

    • 您也可以使用 NSProcessInfo,就像在 Objective-C 中一样。
    • NSProcessInfo 需要 Foundation。我的回答不需要基金会。只需使用 swift lang 标准库。
    • C_ARCG 似乎不再受支持。
    • 我可以确认 C_ARG 不再适用于最新版本的工具,即 XCode 版本 7.1 (7B91b)。
    【解决方案4】:

    任何想要使用旧的“getopt”(在 Swift 中可用)的人都可以将此作为参考。我用 C 语言制作了 GNU 示例的 Swift 端口,可以在以下位置找到:

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

    带有完整的描述。它已经过测试并且功能齐全。它也不需要 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)])!)'")
    }
    

    【讨论】:

      【解决方案5】:

      Apple 发布了 ArgumentParser 库来执行此操作:

      我们很高兴地宣布 ArgumentParser,这是一个新的开源库,它使操作变得简单——甚至令人愉快! — 在 Swift 中解析命令行参数。

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


      Swift 参数解析器

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

      首先声明一个类型,该类型定义了您需要从命令行收集的信息。使用ArgumentParser 的属性包装器之一装饰每个存储的属性,并声明符合ParsableCommand

      ArgumentParser 库解析命令行参数,实例化您的命令类型,然后执行您的自定义 run() 方法或退出并显示有用的消息。

      【讨论】:

        【解决方案6】:

        您可以使用 CommandLine.arguments 数组创建参数解析器并添加您喜欢的任何逻辑。

        你可以测试一下。创建文件arguments.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)
        }
        

        编译并运行它:

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

        构建自己的参数解析器的问题是考虑到所有命令行参数约定。我建议使用现有的 Argument Parser。

        你可以使用:

        • Vapor 的控制台模块
        • Swift 包管理器使用的 TSCUtility 参数解析器
        • Apple 开源的 Swift 参数解析器

        我已经写过如何在这三个工具上构建命令行工具。您应该查看它们并确定最适合您的风格。

        如果你有兴趣,这里是链接:

        【讨论】:

          猜你喜欢
          • 2022-01-19
          • 2013-07-16
          • 1970-01-01
          • 1970-01-01
          • 2014-01-30
          • 2011-03-21
          • 1970-01-01
          相关资源
          最近更新 更多