I'm trying to run shell commands using Swift in my OSX app.
Running basic commands such as echo work fine but the following throws
"env: node: No such file or directory"
@IBAction func streamTorrent(sender: AnyObject) {
shell("node", "-v")
}
func shell(args: String...) -> Int32 {
let task = NSTask()
task.launchPath = "/usr/bin/env"
task.arguments = args
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
I also get "sh: node: command not found" when running the system command.
system("node -v")
Update:
Not as nice as some of the suggestions below, but I managed to echo the command into a file and have it opened and executed in terminal:
system("echo node -v > ~/installation.command; chmod +x ~/installation.command; open ~/installation.command")
Looked into this a bit more.
The nodejs
installer uses /usr/local/bin
, which is not included in the PATH
for applications launched from Finder:
/usr/bin:/bin:/usr/sbin:/sbin
The directory is included in the PATH
set for bash
via /etc/profile
& path_helper:
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
Options:
Just write /usr/local/bin/node
instead of node
.
Tweak the PATH
used by NSTask
via the environment
property.
Use setenv to change the PATH
for system
— will also affect NSTask
.
- Execute
bash
as a login shell. See the man page for details.
func shell(command: String) -> Int32 {
let task = NSTask()
task.launchPath = "/usr/bin/env"
task.arguments = ["bash", "-c", command]
task.launch()
task.waitUntilExit()
return task.terminationStatus
}
So you can do shell("node -v")
which I find more convenient:
"sh: node: command not found"
Obviously, node
is not an absolute path.
Sounds like you've made changes to ~/.bash_profile
or another file to include the location of node
in the PATH
environment variable.
system
is launching bash
using sh -c
.
I forget what the rules are exactly, but bash
will ignore at least some configuration files when executed this way. Presumably, your changes to PATH
are not being read or applied.
"env: node: No such file or directory"
Again, node
is not an absolute path. NSTask
doesn't use a shell, so any processes you execute will inherit your application's environment variables. In most cases, this means the default PATH
.
If you need a custom environment for NSTask
, grab the environment
dictionary from NSProcessInfo
, make your changes & then set NSTask
's environment
property.