mac运行linux命令,iOS:mac.app执行shell命令

报错

1:

错误:

/bin/bash: line 1: /Users/liuyaqiang/Desktop/GitHub/KTMRobot/auto.sh: Operation not permitted

解决方法:

Singing&Capabilitiesy移除AppSandbox

代码

import Cocoa

class CommandRunner: NSObject {

/** 同步执行

* command: shell 命令内容

* returns: 命令行执行结果,积压在一起返回

*

* 使用示例

let (res, rev) = CommandRunner.sync(command: "ls -l")

print(rev)

*/

static func sync(command: String) -> (Int, String) {

let utf8Command = "export LANG=en_US.UTF-8\n" + command

return sync(shellPath: "/bin/bash", arguments: ["-c", utf8Command])

}

/** 同步执行

* shellPath: 命令行启动路径

* arguments: 命令行参数

* returns: 命令行执行结果,积压在一起返回

*

* 使用示例

let (res, rev) = CommandRunner.sync(shellPath: "/usr/sbin/system_profiler", arguments: ["SPHardwareDataType"])

print(rev)

*/

static func sync(shellPath: String, arguments: [String]? = nil) -> (Int, String) {

let task = Process()

let pipe = Pipe()

var environment = ProcessInfo.processInfo.environment

environment["PATH"] = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

task.environment = environment

if arguments != nil {

task.arguments = arguments!

}

task.launchPath = shellPath

task.standardOutput = pipe

task.launch()

let data = pipe.fileHandleForReading.readDataToEndOfFile()

let output: String = String(data: data, encoding: String.Encoding.utf8)!

task.waitUntilExit()

pipe.fileHandleForReading.closeFile()

return (Int(task.terminationStatus), output)

}

/** 异步执行

* command: shell 命令内容

* output: 每行的输出内容实时回调(主线程回调)

* terminate: 命令执行结束状态(主线程回调)

*

* 使用示例

CommandRunner.async(command: "ls -l",

output: {[weak self] (str) in

self?.appendLog(str: str)

},

terminate: {[weak self] (code) in

self?.appendLog(str: "end \(code)")

})

*/

static func async(command: String,

output: ((String) -> Void)? = nil,

terminate: ((Int) -> Void)? = nil) {

let utf8Command = "export LANG=en_US.UTF-8\n" + command

async(shellPath: "/bin/bash", arguments: ["-c", utf8Command], output:output, terminate:terminate)

}

/** 异步执行

* shellPath: 命令行启动路径

* arguments: 命令行参数

* output: 每行的输出内容实时回调(主线程回调)

* terminate: 命令执行结束状态(主线程回调)

*

* 使用示例

CommandRunner.async(shellPath: "/usr/sbin/system_profiler",

arguments: ["SPHardwareDataType"],

output: {[weak self] (str) in

self?.appendLog(str: str)

},

terminate: {[weak self] (code) in

self?.appendLog(str: "end \(code)")

})

*/

static func async(shellPath: String,

arguments: [String]? = nil,

output: ((String) -> Void)? = nil,

terminate: ((Int) -> Void)? = nil) {

DispatchQueue.global().async {

let task = Process()

let pipe = Pipe()

let outHandle = pipe.fileHandleForReading

var environment = ProcessInfo.processInfo.environment

environment["PATH"] = "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin"

task.environment = environment

if arguments != nil {

task.arguments = arguments!

}

task.launchPath = shellPath

task.standardOutput = pipe

outHandle.waitForDataInBackgroundAndNotify()

var obs1 : NSObjectProtocol!

obs1 = NotificationCenter.default.addObserver(forName: NSNotification.Name.NSFileHandleDataAvailable,

object: outHandle, queue: nil) { notification -> Void in

let data = outHandle.availableData

if data.count > 0 {

if let str = NSString(data: data, encoding: String.Encoding.utf8.rawValue) {

DispatchQueue.main.async {

output?(str as String)

}

}

outHandle.waitForDataInBackgroundAndNotify()

} else {

NotificationCenter.default.removeObserver(obs1)

pipe.fileHandleForReading.closeFile()

}

}

var obs2 : NSObjectProtocol!

obs2 = NotificationCenter.default.addObserver(forName: Process.didTerminateNotification,

object: task, queue: nil) { notification -> Void in

DispatchQueue.main.async {

terminate?(Int(task.terminationStatus))

}

NotificationCenter.default.removeObserver(obs2)

}

task.launch()

task.waitUntilExit()

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这段代码的问题在于,它在每次写入日志时都会打开和关闭文件。这种操作会导致不必要的文件I/O开销,影响性能,并且可能会导致文件锁定和竞争问题。在高并发的情况下,这可能会导致程序崩溃或数据丢失。 为了解决这个问题,可以将文件打开的操作移动到构造函数中,这样只需要在对象创建时打开一次文件,然后在析构函数中关闭文件。同时,可以添加一个缓冲区,以便在缓存中收集足够的数据后,再一次性地将其写入文件。这可以通过使用`std::endl`或`std::flush`来实现。 例如,修改后的代码可能如下所示: ``` class MyLog { public: MyLog(const std::string& logFilePath); ~MyLog(); void toLogA(const std::string& str); private: std::ofstream file; std::string logFilePath; std::stringstream buffer; }; MyLog::MyLog(const std::string& logFilePath) { this->logFilePath = logFilePath; this->file.open(logFilePath.c_str(), std::ios::app); } MyLog::~MyLog() { if (this->file.is_open()) this->file.close(); } void MyLog::toLogA(const std::string& str) { buffer << str << "\n"; if (buffer.str().length() > 1024) { // 缓冲区大小达到1024时写入文件 file << buffer.str(); file.flush(); buffer.str(""); } } ``` 这样,每次调用`toLogA()`方法时,日志信息都会被写入缓冲区中。当缓冲区大小达到1024时,缓冲区中的内容会被写入文件,并清空缓冲区。在对象销毁时,文件会被自动关闭。这种方法可以避免频繁的文件I/O操作,提高性能,同时减少文件锁定和竞争问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值