繁体   English   中英

命令行“无法访问启动路径”

[英]Command line “launch path not accessible”

我最近发现我可以创建 Swift 命令行脚本。

我决定看看是否可以使用它构建我的 Xamarin 项目。

不幸的是,我收到以下错误,我不知道如何修复它。

*** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“启动路径不可访问”

这是我的脚本:

#!/usr/bin/env swift

import Foundation

print("Building Script")

let fileManager = NSFileManager.defaultManager()
let path = fileManager.currentDirectoryPath

func shell(launchPath: String, arguments: [String] = []) -> NSString? {

    let task = NSTask()
    task.launchPath = launchPath
    task.arguments = arguments

    let pipe = NSPipe()
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = NSString(data: data, encoding: NSUTF8StringEncoding)

    return output
}

if let output = shell("/Applications/Xamarin\\ Studio.app/Contents/MacOS/mdtool", arguments: ["-v build", "\"--configuration:Beta|iPhone\"", "MyApp.iOS.sln"]) {
    print(output)
}

有什么想法吗?

认为问题是你实际上是想执行shell并让它执行mdtool,而不是直接执行mdtool

尝试传递“/bin/bash”作为启动路径,然后将 mdtool 的路径作为参数字符串的一部分。

最近我遇到了类似的问题,但我的解决方案不同。

我通过更改脚本的权限模式来解决这个问题。 具体来说, chmod 777 xxx 关键是给予执行权限。

让我们进行一个对照实验来验证它:

  1. 准备一个带有路径/tmp/a.sh和权限666的脚本

    /tmp/a.sh的内容:

#!/bin/sh
echo aaa
  1. 准备一个swift脚本来启动脚本:
import Foundation

let fileManager = FileManager.default
let path = fileManager.currentDirectoryPath

func shell(launchPath: String, arguments: [String] = []) -> NSString? {

    let task = Process()
    task.launchPath = launchPath
    task.arguments = arguments

    let pipe = Pipe()
    task.standardOutput = pipe
    task.launch()

    let data = pipe.fileHandleForReading.readDataToEndOfFile()
    let output = NSString(data: data, encoding: String.Encoding.utf8.rawValue)

    return output
}

if let output = shell(launchPath: "/tmp/a.sh", arguments: []) {
    print(output)
}

输出是:

... *** Terminating app due to uncaught exception 'NSInvalidArgumentException', 
reason: 'launch path not accessible'
  1. /tmp/a.sh的权限改为777 (通过授予执行权限),然后重新运行swift脚本:
aaa

我的版本旨在突出各种预期结果。 您可以将ParsingError.encodingFailureOS.Error.processFailure替换为您自己的Error实现。

/// Getting a `Result` from a shell command
public func process(_ command: String) -> Result<String, Swift.Error> {
    let process = Process()
    process.launchPath = "/bin/bash"
    process.arguments = ["-c", command]

    let outputPipe = Pipe()
    process.standardOutput = outputPipe
    let errorPipe = Pipe()
    process.standardError = errorPipe

    process.launch()

    let outputData = outputPipe.fileHandleForReading.readDataToEndOfFile()
    guard let output = String(data: outputData, encoding: .utf8) else {
        return .failure(ParsingError.encodingFailure(data: outputData))
    }

    let errorData = errorPipe.fileHandleForReading.readDataToEndOfFile()
    guard let errorOutput = String(data: errorData, encoding: .utf8) else {
        return .failure(ParsingError.encodingFailure(data: errorData))
    }

    process.waitUntilExit()
    let status = Int(process.terminationStatus)

    if status == 0, errorOutput.isEmpty {
        return .success(output)
    } else {
        return .failure(OS.Error.processFailure(code: status, message: errorOutput))
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM