Is it possible to create a single Mac OS X app that can be run strictly from the *nix command-line (using stdin/stdout, from the Terminal console or via ssh, etc.), but also be launchable from an app icon and using the Mac GUI for all user interaction (no Terminal required)? If so, how?
I can already achieve something like this using two executables, one a GUI front-end for the other, with pipes, sockets, shared memory, or Applescript (et.al.) for communication. This question is whether I can do this using a single executable and single app process space.
Is there a way to do this without passing a new command-line argument to the command-line executable? (as there are legacy issues related to use of the command-line app).
What you're looking for, I believe, is a way to determine if you are launched from the GUI or the command line. A simple way would be to get your parent process identifier. If you're a GUI process, you are started by launchd (the user session launchd). If you are a command line, then a shell or script has started you (at any rate, NOT launchd).
Now, how to do so - a simple way would be to use the proc_info system call (#336), which is conveniently wrapped by libproc (check <libproc.h>
. Specifically, you would want proc_bsdinfo (see <sys/proc_info.h>
) which has the pbi_ppid field to specify your parent (and pbi_comm of the parent would tell you its name - to see if it's launchd). You could implement command line functionality by checking your parent right before you go into NSApplicationMain
.
(As in other answers, your binary will end up in your .app/Contents/MacOS/<binary>
, so yes, a symlink makes sense)
I'm not 100% sure whether this'll work, but the documentation for the LSEnvironment
key in Info.plist
seems to indicate that the specified environment variables will only be defined when your application is launched by Finder.
If you were to define a variable in LSEnvironment
(let's call it MYAPP_GUI
) and check its value at launch, it should exist when using Finder and not when using Terminal. That'll tell you whether or not to show GUI or use stdio
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With