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

Swift调用Bash执行mobiledevice完整命令提示“command not found”求助

Troubleshooting "command not found" for mobiledevice in Swift's Process

Hey there! I see you're running into a "command not found" error when trying to execute the full mobiledevice get_device_prop DeviceName command from your Swift function, even though running just mobiledevice works. Let's break down what's happening and fix it.

The Root Cause

When you launch bash with --login, it loads a specific set of profile files (like .bash_profile, .bashrc) that might not include the directory where mobiledevice is installed. Your terminal session probably has the correct PATH environment variable to find mobiledevice, but the Process instance in Swift doesn't inherit that same full environment by default—especially when using --login which can reset or modify the path.

Fix 1: Use the Absolute Path to mobiledevice

The simplest fix is to call mobiledevice using its full absolute path. First, find where it's installed by running this in your terminal:

which mobiledevice

This will return something like /usr/local/bin/mobiledevice. Then update your Swift function to use that path:

func getConnectedDevices(lblOut: NSTextView) {
    let pipe = Pipe()
    let process = Process()
    
    // Replace with the path from `which mobiledevice`
    let mobiledeviceAbsolutePath = "/usr/local/bin/mobiledevice"
    process.launchPath = "/bin/bash"
    process.arguments = ["--login", "-c", "\(mobiledeviceAbsolutePath) get_device_prop DeviceName"]
    
    process.standardOutput = pipe
    let fileHandle = pipe.fileHandleForReading
    
    process.launch()
    
    // Avoid force-unwrapping to prevent crashes if output is invalid
    if let output = String(data: fileHandle.readDataToEndOfFile(), encoding: .utf8) {
        lblOut.string += "\n" + output
    } else {
        lblOut.string += "\nError: Could not read command output"
    }
}

Fix 2: Explicitly Set the PATH Environment Variable

If you prefer not to hardcode the path, you can add the directory containing mobiledevice to the Process environment's PATH:

func getConnectedDevices(lblOut: NSTextView) {
    let pipe = Pipe()
    let process = Process()
    
    // Get the current environment and add the mobiledevice directory to PATH
    var environment = ProcessInfo.processInfo.environment
    let mobiledeviceDirectory = "/usr/local/bin" // Replace with the correct directory
    if let existingPath = environment["PATH"] {
        environment["PATH"] = "\(mobiledeviceDirectory):\(existingPath)"
    } else {
        environment["PATH"] = mobiledeviceDirectory
    }
    process.environment = environment
    
    process.launchPath = "/bin/bash"
    process.arguments = ["--login", "-c", "mobiledevice get_device_prop DeviceName"]
    
    process.standardOutput = pipe
    let fileHandle = pipe.fileHandleForReading
    
    // Use run() instead of launch() (Swift 5.3+ recommended)
    do {
        try process.run()
        process.waitUntilExit()
        if let output = String(data: fileHandle.readDataToEndOfFile(), encoding: .utf8) {
            lblOut.string += "\n" + output
        } else {
            lblOut.string += "\nError: Could not read command output"
        }
    } catch {
        lblOut.string += "\nError running command: \(error.localizedDescription)"
    }
}

Bonus: Use run() Instead of launch()

Note that launch() is deprecated in newer Swift versions. Using try process.run() with proper error handling is more robust, as shown in Fix 2.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:01:14