You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift开发macOS进程监控App执行ps命令提示操作不被允许

macOS应用执行ps x报“operation not permitted”的解决方法

你开发的macOS进程监控应用,通过Process调用zsh执行ps x时出现权限错误,但执行普通命令(如ls -a)正常,且已添加授权文件仍未解决,可尝试以下几种方案:

  • 检查系统级完全磁盘访问权限
    打开「系统设置」→「隐私与安全性」→「完全磁盘访问权限」,找到你的应用(若为Xcode调试运行,可同时添加Xcode到列表)并勾选权限。macOS Catalina及以后版本中,ps属于受TCC框架管控的工具,需要该权限才能正常访问系统进程信息。

  • 调整App Sandbox设置
    若项目开启了App Sandbox:

    • 先尝试临时关闭沙盒(在Xcode「签名与功能」面板中取消勾选App Sandbox),测试ps x是否能正常执行;
    • 若必须保留沙盒,需在授权文件(entitlements)中添加路径访问例外:
      <key>com.apple.security.temporary-exception.files.absolute-path.read-only</key>
      <array>
        <string>/bin/ps</string>
      </array>
      
      但这种方式限制较多,仅适合特定场景。
  • 直接执行ps命令而非通过zsh中转
    当前代码通过zsh间接执行命令,可能额外引入权限继承问题。改为直接调用ps进程:

    func runPSCommand() -> String {
      let task = Process()
      let pipe = Pipe()
    
      task.standardOutput = pipe
      task.standardError = pipe
      task.launchPath = "/bin/ps"
      task.arguments = ["x"]
      task.standardInput = nil
      task.launch()
    
      let data = pipe.fileHandleForReading.readDataToEndOfFile()
      guard let output = String(data: data, encoding: .utf8) else {
        return ""
      }
      return output
    }
    
  • 验证代码签名与授权文件关联
    在Xcode「Build Settings」→「Code Signing Entitlements」中,确认授权文件的路径配置正确;同时确保Xcode本身拥有足够权限(如加入完全磁盘访问),调试时进程权限会继承自Xcode。

  • 使用官方API替代shell命令
    对于进程监控场景,建议直接调用macOS系统API(如libproc库)获取进程信息,避免依赖shell命令,更符合Apple生态规范且无权限问题:

    import Foundation
    import System
    
    func getAllProcessIDs() -> [pid_t] {
      var processes: [pid_t] = []
      let bufferSize = 1024
      var pidBuffer = [pid_t](repeating: 0, count: bufferSize)
      let count = proc_listpids(PROC_ALL_PIDS, 0, &pidBuffer, UInt32(MemoryLayout<pid_t>.stride * bufferSize))
      if count > 0 {
        processes = Array(pidBuffer[0..<Int(count)])
      }
      return processes
    }
    
    // 示例:获取指定PID的进程名称
    func getProcessName(for pid: pid_t) -> String? {
      var procInfo = proc_bsdinfo()
      let result = proc_pidinfo(pid, PROC_PIDTBSDINFO, 0, &procInfo, UInt32(MemoryLayout<proc_bsdinfo>.stride))
      guard result > 0 else { return nil }
      return String(cString: &procInfo.pbi_name)
    }
    

内容的提问来源于stack exchange,提问作者deniswsrosa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 00:25:34