Convert Shell Script To * .app File
Using Automator.app and Platypus.app, I was able to bundle a simple shell script built to work with Wi-Fi on my MacBook Pro. Both the resulting applications work correctly, but there is one clear problem that I want to fix: applications refer to the shell script from outside the program. How can I embed a wrapper script and reference it from within the application resources so that the application can run even if the original source file is moved?
source to share
Just to mention this, if you get information about the script, you can set it to open with a terminal. When double clicked, it will run the script.
Otherwise, wrapping a script in the .app pool is trivial. Mac OS X will happily run any script identified as an application executable.
At a minimum, you need the following structure:
- (name) .app
- Content
- MacOS
- (name)
- MacOS
- Content
If file (name) is your script (which should be executable and should have a shebang line). (name) must be identical in the .app directory and the script file: for example, if your application directory is named "My Shell Script.app" then the file inside the macOS directory must be called "My Shell Script", no extension .
If this is inconvenient, you can use the Info.plist file to specify an alternate name for the executable file. Info.plist is located in the Contents directory:
- Wrapper.app
- Content
- Info.plist
- MacOS
- MyScript
- Content
This structure (MyScript executable in Wrapper.app) works if you specify MyScript as CFBundleExecutable
in the property list:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>MyScript</string>
</dict>
</plist>
Using the Info.plist file is probably preferable, as it will allow you to rename your shell without breaking it.
Here's one example script that uses it /bin/sh
as an interpreter, but you really could do anything ( #!/usr/bin/swift
, #!/usr/bin/python
etc.).
#!/bin/sh
open -a Calculator
The script will run when you double click on the appset.
You can link whatever you need with your script in the directory Contents
. If you feel like you can reproduce the standard executable package layout with a directory Resources
, etc.
source to share
While this works, there seems to be no way to access the content directory from a script. It cannot be passed to environment variables in bash or anywhere else I can find. This makes it difficult to package stuff into the Contents directory as it appears to be inaccessible by a bash script. There are various hacking techniques on the web, but they all involve efficiently searching for a script by name, which means that if there are two versions of an application in two places, it will crash. Anyone work it out?
source to share