Operation not permitted when executing 'killall' with Swift
Mac apps, like iOS apps, are sandboxed by default, which means they have very limited access to system resources. They are only allowed to read and write to a small number of sandboxed directories, for example, and read/write/execute from usr/bin
is most definitely not allowed, and nor will you be allowed to launch processes.
As I recall, by deleting your entitlements file you are building an app that isn't sandboxed. You can run it from Xcode, but will need to change your system settings in order to be able to run it from the finder.
Kill process in swift
I'd suggest you first read the man
page for sysctl
-- it's used to get and set kernel state. Does that sound like something you want?
The path to killall
is /usr/bin/killall
, which you can find from Terminal:
> which killall
/usr/bin/killall
Here's the full Swift code:
let pipe = Pipe()
let task = Process()
task.launchPath = "/usr/bin/killall"
task.arguments = ["iTunes"]
task.standardOutput = pipe
task.standardError = pipe
task.launch()
task.waitUntilExit()
let data = pipe.fileHandleForReading.readDataToEndOfFile()
if let output = String(data: data, encoding: .utf8) {
print(output)
}
Execute a terminal command from a Cocoa app
You can use NSTask
. Here's an example that would run '/usr/bin/grep foo bar.txt
'.
int pid = [[NSProcessInfo processInfo] processIdentifier];
NSPipe *pipe = [NSPipe pipe];
NSFileHandle *file = pipe.fileHandleForReading;
NSTask *task = [[NSTask alloc] init];
task.launchPath = @"/usr/bin/grep";
task.arguments = @[@"foo", @"bar.txt"];
task.standardOutput = pipe;
[task launch];
NSData *data = [file readDataToEndOfFile];
[file closeFile];
NSString *grepOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog (@"grep returned:\n%@", grepOutput);
NSPipe
and NSFileHandle
are used to redirect the standard output of the task.
For more detailed information on interacting with the operating system from within your Objective-C application, you can see this document on Apple's Development Center: Interacting with the Operating System.
Edit: Included fix for NSLog problem
If you are using NSTask to run a command-line utility via bash, then you need to include this magic line to keep NSLog working:
//The magic line that keeps your log where it belongs
task.standardOutput = pipe;
An explanation is here: https://web.archive.org/web/20141121094204/https://cocoadev.com/HowToPipeCommandsWithNSTask
How do I run a terminal command in a Swift script? (e.g. xcodebuild)
If you don't use command outputs in Swift code, following would be sufficient:
#!/usr/bin/env swift
import Foundation
@discardableResult
func shell(_ args: String...) -> Int32 {
let task = Process()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
shell("ls")
shell("xcodebuild", "-workspace", "myApp.xcworkspace")
Updated: for Swift3/Xcode8
Related Topics
Swift 2.2, Contains Method Not Working
Swift Error Comparing Two Arrays of Optionals
Difference Between Static Enum and Static Struct
No Designated Init for Skshapenode(Circleofradius: Radius)
Swift 2: Invalid Conversion from Throwing Function of Type to Non-Throwing Function
Swift: Accessing Computed Property Through Pointer
Need Explanation About Random Function Swift
Using Foreach with a String Array - [String] Has No Member 'Identified'
Swift ? Must Be Followed by a Call, Member Lookup, or Subscript
Table View Cellforrowatindexpath Warning
What's Wrong with My #If Target_Os_Simulator Code for Realm Path Definition
How to Create and Access Share App Group Document Directory
Dynamic Datasource/Delegates for Uitableview in Swift
Swift: For-In Loop Requires '[Deepspeechtokenmetadata]' to Conform to 'Sequence'
Dyld: Library Not Loaded, App Requires Afnetworking 2.0.0 But Provides Version 1.0.0