2

I am trying to run the following two bash commands in a Cocoa app:

defaults write com.apple.finder CreateDesktop false
killall Finder

Using NSTask, I have the following Swift code to execute the command when a button is clicked:

let commands = ["-c", "defaults write com.apple.finder CreateDesktop false",
                "-c", "killall Finder"]

let task = NSTask()
task.launchPath = "/bin/bash"
task.arguments = commands
task.launch()

I get no errors when running the code. But nothing actually happens when the button is clicked. Any suggestions?

wigging
  • 8,492
  • 12
  • 75
  • 117

1 Answers1

2

Are you sure nothing happens? You cannot pass multiple -c arguments to Bash like that, but mine does execute the first command when I try.

$ bash -c 'echo foo' -c 'echo bar'
foo

In this particular case, the workaround is simple;

$ bash -c 'echo foo; echo bar'
foo
bar

More generally, the individual commands you were passing in to Bash do not need a shell at all. To just kill Finder,

task.launchPath = "/usr/bin/killall"
task.arguments = [ "Finder" ]

but given that you do have multiple commands, running them from a shell actually makes sense.

let task = NSTask()
task.launchPath = "/bin/bash"
task.arguments = ["-c",
     "defaults write com.apple.finder CreateDesktop false; killall Finder"]
task.launch()
tripleee
  • 175,061
  • 34
  • 275
  • 318
  • Running the commands as one line using the `;` works. So apparently, you have to combine multiple lines as one string in the arguments array. For example, `["-c", "command 1; command 2; command 3"]` would run all the commands. So if you have a lot of commands, would it be best to put all those commands in a shell script then run that shell script from the app? – wigging Oct 28 '14 at 17:24
  • Modularity is good, but depending on an external script adds another kind of complexity. If it's just a sequence of a few commands, I would keep them in a hard-coded string for now. For what it's worth, newlines are valid command terminators, too. – tripleee Oct 28 '14 at 17:53
  • Oh, and if this is a situation where any sort of privileges are involved, fifty-eleven ugly little subprocesses is way better than exposing the attack surface that is the shell. – tripleee Oct 28 '14 at 18:14