pka*_*amb 5 macos bash shell scripting swift
我正在开发一项功能,以启用将由Mac应用程序执行的用户提供的脚本.
NSUserScriptTask
作为脚本调用代码的基础,而子类NSUserAppleScriptTask
和NSUserAutomatorTask
子类都允许设置变量以将信息从Swift传递给脚本:
设置NSUserAutomatorTask变量,而不需要Automator工作流来声明该变量
离开了NSUserUnixTask
,它不支持设置变量.它改为支持一个[String]
名为的数组arguments
.
执行脚本时,我想要从Mac应用程序传递3个变量:
let folderURL: String? = "/files/"
let fileURLs: [String] = ["/files/file1", "/files/file2"]
let selectionType: Int? = 1
let arguments: [String] = ["how", "should", "arguments", "be", "formatted", "?"]
let unixScript = try! NSUserUnixTask(url: url)
unixScript.execute(withArguments: arguments) { (error) in
if let error = error {
print(error)
}
}
Run Code Online (Sandbox Code Playgroud)
必须将3个swift变量压缩为单个[String]
数组NSUserUnixTask
以用作其arguments
参数.
当脚本运行时,我希望以原型方式为脚本作者提供相同参数的访问权限:
#! /bin/bash
say "How should the script then access/parse the arguments?"
say $@ #says the arguments
Run Code Online (Sandbox Code Playgroud)
基于脚本作者的易用性,Swift代码应该如何将其信息格式化为参数[String]
?
可以提供哪些样板代码,以便从脚本中轻松实用地访问参数?
有很多方法可以做到这一点,具体取决于 shell 脚本程序员的期望。如果我是其中之一,我会要求你保持简单:
-flag value
)按照您的示例,稍加修改:
import Foundation
let shellScript = CommandLine.arguments[1]
let folderURL: String = "/files/"
let fileURLs: [String] = ["/files/file1", "/files/file2"]
let selectionType: Int? = 1
var arguments = [String]()
// script.sh <folder> [-type <type>] file1, file2, ...
arguments.append(folderURL) // <folder> is mandatory
if let type = selectionType { // -type <type> is optional
arguments.append("-type")
arguments.append("\(type)")
}
arguments += fileURLs // file1, ... (if it can't be empty check it here)
assert(FileManager.default.fileExists(atPath: shellScript))
let unixScript = try! NSUserUnixTask(url: URL(fileURLWithPath: shellScript))
let stdout = FileHandle.standardOutput
unixScript.standardOutput = stdout
unixScript.execute(withArguments: arguments) { error in
if let error = error {
print("Failed: ", error)
}
exit(0)
}
dispatchMain() // I'm not swift script expert, there may be a better way
Run Code Online (Sandbox Code Playgroud)
以及相应的shell脚本:
#!/bin/bash
# mandatory positional arguments
FOLDER=$1 && shift
# other mandatory arguments goes here
TYPE=7 # default type
FILES=()
while [[ $# -gt 0 ]]; do
arg=$1
case $arg in
-type)
TYPE=$2 && shift && shift
;;
# other named parameters here
*)
FILES+=($1) && shift
;;
esac
done
echo FOLDER: '<'${FOLDER}'>'
echo TYPE: '<'${TYPE}'>'
echo FILES: '<'${FILES[@]}'>'
exit 0
Run Code Online (Sandbox Code Playgroud)
例子:
ScriptRunner /path/to/script.sh
Run Code Online (Sandbox Code Playgroud)
输出:
FOLDER: </files/>
TYPE: <1>
FILES: </files/file1 /files/file2>
Run Code Online (Sandbox Code Playgroud)
我使用 swift 包管理器来构建:
// swift-tools-version:4.2
import PackageDescription
let package = Package(
name: "ScriptRunner",
dependencies: [],
targets: [
.target(name: "ScriptRunner", dependencies: [])
]
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
293 次 |
最近记录: |