加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift – 如何通过NSUserUnixTask传递参数然后通过脚本访问?

发布时间:2020-12-14 05:01:55 所属栏目:百科 来源:网络整理
导读:我正在开发一项功能,以启用将由Mac应用程序执行的用户提供的脚本. NSUserScriptTask是脚本调用代码的基础,NSUserAppleScriptTask和NSUserAutomatorTask子类都允许设置变量以将信息从Swift传递到脚本: Passing variables to an AppleScript Setting NSUserAu
我正在开发一项功能,以启用将由Mac应用程序执行的用户提供的脚本.

NSUserScriptTask是脚本调用代码的基础,NSUserAppleScriptTask和NSUserAutomatorTask子类都允许设置变量以将信息从Swift传递到脚本:

Passing variables to an AppleScript

Setting NSUserAutomatorTask variables without requiring Automator Workflows to declare that variable

这留下了NSUserUnixTask,它不支持设置变量.它改为支持一个名为arguments的[String]数组.

执行脚本时,我想从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)
    }
}

必须将3个swift变量压缩为单个[String]数组,以便NSUserUnixTask用作其参数参数.

当脚本运行时,我希望以原型方式为脚本作者提供相同参数的访问权限:

#! /bin/bash 
say "How should the script then access/parse the arguments?"
say $@ #says the arguments

根据脚本作者的易用性,Swift代码应该如何将其信息格式化为参数[String]?

可以提供哪些样板代码,以便从脚本中轻松实用地访问参数?

解决方法

有很多方法可以做,具体取决于shell脚本程序员所期望的.如果我是其中之一,我会要求你保持简单:

>位置参数(开始时必需参数的固定数量)
>可选的命名参数(样式的任何参数-flag值)
>更多参数(可变数量的附加参数)

按照你的例子,稍加修改:

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

和相应的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

例:

ScriptRunner /path/to/script.sh

输出:

FOLDER: </files/>
TYPE: <1>
FILES: </files/file1 /files/file2>

我使用swift包管理器来构建:

// swift-tools-version:4.2

import PackageDescription

let package = Package(
    name: "ScriptRunner",dependencies: [],targets: [
        .target(name: "ScriptRunner",dependencies: [])
    ]
)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读