Installing apps on MacOS from the terminal
I love working on a mac. The Hardware’s good (altho with some caveats) and the software is even better. I personally believe most of the hate that MacOS gets is unwarranted. Windoze deserves all of it tho lol 😝. I’ve been basically living in the terminal ever since i got to coding/programming in 2022. So, I’m super comfortable with working with CLIs and the terminal in general. In fact, it’s my preferred way of interacting with my laptop. Of course, I use GUI when i have to, but most of all the daily tasks, like navigating folders, making notes and viewing videos, I do it thru the terminal.
The process of “installing” apps on macos is super ez. You just mount a disk image .dmg
(which is the way of distributing apps) then copy the app bundle to the Applications folder. I have no idea how you make an app installation process easier than this, yet it garnered hate on twitter X the other day. Which I do not get at all. You do have the other method of using a package manager like Brew or MacPorts but sometimes apps are only distributed as disk images.
So me being the weird aah nerd i am, i looked into how i could do the app installation process thru the terminal.
- The first step is getting the disk image itself. You could either download it thru a browser itself or use
curl
orwget
. I prefer to do this step in the browser cause you gotta do some navigating the web to find the download page for the app anyways. You could use curl/wget if you want to automate this process with a bash script or some other way.
# curl requires an extra flag to download a file, because by default, curl just dumps the contents to the stdout
# the `-O` flag saves the file as the same name as the remote filename.
curl -O https://updates.signal.org/desktop/signal-desktop-mac-universal-7.38.0.dmg
# wget works simply with the url
wget https://updates.signal.org/desktop/signal-desktop-mac-universal-7.38.0.dmg
- The next step is to mount the disk image. There are again two methods to do so. You could either use the
open
command or usehdiutil
.open
is a macos command to open a file and directory in whichever default application is selected for file-type. Using this to mount a disk image/ISO, uses Disk Image Mounter utility to mount the disk, which is a GUI so that’s that. The other way is to use thehdiutil
with themount
subcommand to mount disks, which is more in line with the whole “do it thru the terminal” idea.
# Using open
open ~/Downloads/signal-desktop-mac-universal-7.38.0.dmg
# Using hdiutil
hdiutil mount ~/Downloads/signal-desktop-mac-universal-7.38.0.dmg
- All disks on macos are mounted to the
/Volumes
root directory. You can navigate to it using thecd
command. If the mounted disk name has spaces in it, wrap the path with single/double quotes or you’ll have to escape the space with \, which makes the command slightly harder to read in my opinion.
# make sure not to forget the leading /
cd "/Volumes/Signal 7.37.0-universal"
- Now we get to actually installting the app. MacOS applications are basically just directories which have a predefined folder structure and hierarchy. Here is the struture of a MacOS app:
foo.app/
Contents/
Info.plist
MacOS/
foo
Resources/
foo.icns
Info.plist
is an XML file that contains all the required metadata for the app. MacOS
is where the binary/executable lives and Resources
is where all the static resources like icons, media files, etc. Keeping this in mind, we can’t simply copy this app bundle to our Applications folder. It will error out complaining that the ur trying to copy a folder.
# this command requires elevated permissions cause we are copying files into the root directory.
# the `-R` flag copies the directory (Signal.app in this case) and the entire subtree to the destination folder.
# Once again, don't forget the leading `/` for the Applications folder
sudo cp -R ./Signal.app /Applications/
- You might not be able to run your application just yet, depending on if the developer signed and notorized it or not. MacOS “quarantines” such files by adding a “com.apple.quarantine” attribute to the file metadata which signals the OS to prompt the user to not open the app as it is “untrusted”. One way to bypass this is by opening the app once, then going in to System Preferences > Privacy & Security > Security > Click “Open” then “Open Anyways” > put in your password when prompted and done!. But obviously, it’s too many steps and clicks. This can be easily done with a single command in the terminal
# the -d flag unsets the given attribute
# the -r flag does this recursively on all the files in the directory/app bundle.
xattr -d -r com.apple.quarantine /Applications/Signal.app
Now you should be able to run your application from the Launchpad or if you wanna stick with the theme with the following commands
# the -a flag directs the open command to use the specified app to open the file but as we are not specifying a file, it just opens the app.
open -a "Signal"
Is this the optimal way to install apps on macos? definitely not. Does this make you look cool in front of your friends? hell yeah. Looking into stuff like this does make u learn what things the GUI abstracts for you and you do get one step closer to becoming one with the machine, which is a W in my books lol.