1

This is the code I can't get to work. If I remove the directory part with the space my shell script runs fine.

shell script simplified is : /usr/bin/find $1 -name *.txt

error with the space is binary operator expected

let bundle = NSBundle.mainBundle()
let path = bundle.pathForResource("doSimpleFind", ofType: "sh")

 let findTask = NSTask()
 let pipe = NSPipe()
 findTask.standardOutput = pipe

 // directory where to search from the script. testing the space in the name
 let constArgsString:String = "/Users/aUser/Library/Application\\ Support"
 //let constArgsString:String = "/Users/aUser/Library/"
 findTask.launchPath = path!
 findTask.arguments = [constArgsString]
 findTask.launch()
 findTask.waitUntilExit()
 let data = pipe.fileHandleForReading.readDataToEndOfFile()
 let outputText:String = NSString(data: data, encoding:NSUTF8StringEncoding)!
 cmdTextResult.textStorage?.mutableString.setString(outputText)
rink.attendant.6
  • 44,500
  • 61
  • 101
  • 156
  • This approach was the only way i was able to pass an argument to a .sh from NSTask. All other examples i've seen launches a command from arguments. But are unable to then pass an argument to the .sh script – Sentry.co Dec 15 '16 at 18:17

2 Answers2

4

NSTask() launches the process "directly" with the given arguments, without using a shell. Therefore it is not necessary to escape any space or other characters in the launch arguments:

let constArgsString = "/Users/aUser/Library/Application Support"

But you have to handle arguments with spaces in your shell script correctly. In your example, $1 needs to be enclosed in double quotes, otherwise it might be passed as multiple arguments to the find command:

/usr/bin/find "$1" -name "*.txt"
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • tested and worked. I tried the for c in "$@" but hadn't tried that without the "\ " in the path. I am surprised that the find command accepts a path with a space in this way, but glad it works. trying to reuse some old scripts. – dirk schelfhout Jan 22 '15 at 21:48
1

Just to make it complete you should obtain the folders path as follow:

let appSupportPath = FileManager.default.urls(for: .applicationSupportDirectory, inDomains: .UserDomainMask).first!.path

or

let libraryPath = FileManager.defaultManager.urls(for: .libraryDirectory, inDomains: .UserDomainMask).first!.path
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571