【发布时间】:2014-07-24 15:25:36
【问题描述】:
如何在 Swift 中访问命令行应用程序的命令行参数?
【问题讨论】:
标签: macos command-line-arguments swift
如何在 Swift 中访问命令行应用程序的命令行参数?
【问题讨论】:
标签: macos command-line-arguments swift
2017 年 1 月 17 日更新:更新了 Swift 3 的示例。Process 已重命名为 CommandLine。
2015 年 9 月 30 日更新:更新了示例以在 Swift 2 中工作。
实际上可以在没有 Foundation 或 C_ARGV 和 C_ARGC 的情况下做到这一点。
Swift 标准库包含一个结构 CommandLine,它有一个名为 arguments 的 Strings 集合。所以你可以像这样打开参数:
for argument in CommandLine.arguments {
switch argument {
case "arg1":
print("first argument")
case "arg2":
print("second argument")
default:
print("an argument")
}
}
【讨论】:
Process.arguments和NSProcessInfo.processInfo().arguments一样吗?
Process 对象现在称为CommandLine 对象。一旦 Swift 3.0 正式发布,这可能会被完全纳入。
【讨论】:
使用顶级常量C_ARGC 和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")
}
}
请注意,我使用的是1..C_ARGC 的范围,因为C_ARGV“数组”的第一个元素是应用程序的路径。
C_ARGV 变量实际上不是数组,而是像数组一样可下标。
【讨论】:
C_ARCG 似乎不再受支持。
任何想要使用旧的“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)])!)'")
}
【讨论】:
Apple 发布了 ArgumentParser 库来执行此操作:
我们很高兴地宣布
ArgumentParser,这是一个新的开源库,它使操作变得简单——甚至令人愉快! — 在 Swift 中解析命令行参数。
https://github.com/apple/swift-argument-parser
首先声明一个类型,该类型定义了您需要从命令行收集的信息。使用
ArgumentParser的属性包装器之一装饰每个存储的属性,并声明符合ParsableCommand。
ArgumentParser库解析命令行参数,实例化您的命令类型,然后执行您的自定义run()方法或退出并显示有用的消息。
【讨论】:
您可以使用 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。
你可以使用:
我已经写过如何在这三个工具上构建命令行工具。您应该查看它们并确定最适合您的风格。
如果你有兴趣,这里是链接:
【讨论】: