Swift 3 macOS应用执行jamf命令报错posix_spawn: error 13求助
Hey there, let's break down this issue you're facing. First off, your hunch about root permissions is spot-on—error 13 corresponds to EPERM (Operation not permitted) in POSIX terms, which almost always means your app lacks the necessary privileges to run that Jamf command.
Why it works in Terminal but not your app
When you run the Jamf command in Terminal, you're probably using sudo to elevate to root privileges (since Jamf policies typically require admin access). But macOS apps run under your current user account by default, and if you've enabled App Sandbox (a standard Xcode setting), your app is locked out of many system-level operations—including executing privileged external commands.
Step-by-Step Solutions
Check App Sandbox Settings
Open your Xcode project, head to the Signing & Capabilities tab, and look for App Sandbox. If it's enabled, try disabling it first (if your app doesn't need sandboxing for the Mac App Store). Sandboxing restricts access to external binaries and system resources, which is likely blocking your Jamf command from running.Elevate to Root Privileges
Since Jamf commands require root access, you'll need to request elevated permissions in your app. Here are two reliable approaches:- Legacy Method (AuthorizationExecuteWithPrivileges)
For older macOS versions compatible with Swift 3, you can use theAuthorizationExecuteWithPrivilegesAPI to run the command as root. Here's a quick code snippet to test:
Note: This API is deprecated in macOS 10.15+, so if you plan to support newer systems, use the next method.import Security let commandPath = "/usr/local/jamf/bin/jamf" let commandArgs = ["policy", "-id", "20"] var authReference: AuthorizationRef? let authStatus = AuthorizationCreate(nil, nil, [], &authReference) if authStatus == errAuthorizationSuccess, let auth = authReference { var outputPipe: Unmanaged<FILE>? let execStatus = AuthorizationExecuteWithPrivileges(auth, commandPath, 0, commandArgs, &outputPipe) // Handle execution status and read output from the pipe here } - Modern Method (SMJobBless)
This is Apple's recommended way to run privileged tasks on modern macOS. You'll need to create a separate helper executable that runs with root privileges, then have your main app request this helper to execute the Jamf command. This requires setting up entitlements for both the app and helper, and registering the helper with launchd. It's more work but complies with macOS's security rules for newer versions.
- Legacy Method (AuthorizationExecuteWithPrivileges)
Confirm Command Path & Environment
Double-check that you're using the full absolute path/usr/local/jamf/bin/jamfin your Swift code. Apps don't inherit the samePATHvariable as Terminal, so relative paths or partial paths might fail even if they work in Terminal.Test with a Non-Privileged Command
To rule out other execution issues, try running a simple command like/bin/echo "Test"in your Swift code. If that works, it confirms the problem is specifically related to root permissions for the Jamf command.
Final Notes
If you're targeting the Mac App Store, sandboxing is required, and using privileged helpers has strict submission guidelines. For enterprise apps (not going to the App Store), disabling sandboxing and using the legacy authorization method might be a quicker fix.
内容的提问来源于stack exchange,提问作者Cameron Wilcox

