Here are some notes about how I configure Mac OS X.
MacPorts¶
MacPorts brings to Mac OS X many programs available on Linux. The programs are compiled from source, which means it can take a while to install everything and that they need the Xcode command line tools installed:
These are installed in /opt/local/
and to use them, you should add /opt/local/bin
to your initialization scripts. (I do this with various configuration files in my configurations project: see for example my ~/.environment_site
file.)
I do not like running these commands as root, so once I install MacPorts, the first thing I do is make everything owned by an unprivledged user (me).
sudo find /opt/local -exec chown mforbes {} \;
This has a couple of complications (see rsync
below) but works well for the most part. If you do this, be sure to run port
without sudo which will be counter to the usual instructions found on the internet. If there is a permissions issue, then check where and deal with it on a case-by-case basis.
Alternatives¶
-
Homebrew provides a popular alternative. From what I can gather from various discussions, MacPorts is more stable, better designed, and more reliable. Some key points are:
- MacPorts installs in
/opt/local
. In contrast, Homebrew puts everything in/usr/local
while also changing the permissions of everything in there to the single user running. This might make sense with a single user – and indeed is similar to what I do with permissions for/opt/local
, but apparently makes it much more difficult for multi-user machines. It also presents a security hazard and is bad practice. For me, this is an issue, because I expect everything in/usr/local
to be customize by me – stuff I install from source for example. - MacPorts installs redundant but isolated libraries, so does not break when Apple updates things. In contrast, Homebrew uses system libraries. Makes it smaller, but less robust.
- MacPorts installs in
Discussions¶
Useful Commands¶
See Common Tasks for more details.
- Information:
port outdated
port installed inactive
port installed requested
port echo leaves
port dependents <portname>
- Marking ports as requested (so they don't appear as leaves)
port setrequested ...
- Updating and Cleaning
port selfupdate
port upgrade outdated
port uninstall inactive
port uninstall leaves # Removes one level of leaves
port uninstall rleaves # Removes all leaves (unrequested ports)
Here is what I typically install:
port install aspell aspell-dict-en
port install ffmpeg +nonfree ImageMagick pngcrush
port install coreutils fswatch gawk wget tree shellcheck ncdu textbrowser
port install gt5
port install cvs bzr git myrepos
port install gsl
port install cmake gmake gperf swig-python
port install symlinks
port install rmtrash
port install munin
port install lua luarocks # For Lmod: see below
port install jq # JSON parser - used for migrating to hg.src.ht
port install multimarkdown
port install py-altgraph graphviz # For visualizing dependencies
port install sshuttle # Tool for simple ssh VPN.
port install smartmontools # Tools for monitoring harddive performance etc.
The rsync
package needs access to /Library/LaunchDaemons
.
sudo chmod a+w /Library/LaunchDaemons
port install rsync
sudo chmod a-w /Library/LaunchDaemons
Cleaning¶
To clean your installation you might want to do the following:
port clean --all all # Can be very slow...
port uninstall inactive
port uninstall rleaves
According to this answer, you might also be able to delete the following:
rm -rf /opt/local/var/macports/software
After installation, my typical setup consumes about 1.7GB of disk space – most of which is due to ffmpeg
:
$ du -sh /opt/local/
1.7G /opt/local/
Dependencies¶
!curl -O https://raw.githubusercontent.com/Synss/macports_deptree/master/port_deptree.py
!pip install --user altgraph
!/opt/local/bin/python27 port_deptree.py python27 | dot -Tpdf | open -fa Preview
#!python port_deptree.py py-altgraph | dot -Tpdf | open -fa Preview
#!python port_deptree.py ffmpeg +nonfree | dot -Tpdf | open -fa Preview
Custom Portfiles¶
If you need to create your own Portfile
or slightly modify an existing one you can quite easily by creating your own Local Portfile Repositories. Here is how I did this using a local repository in ~/src/ports
to edit the sshuttle
Portfile to depend on Python 3.9 (so MacPorts only brings in one version of python).
-
Add
file:///Users/mforbes/src/ports
to/opt/local/etc/macports/sources.conf
.conf # /opt/local/etc/macports/sources.conf ... file:///Users/mforbes/src/ports rsync://rsync.macports.org/release/tarballs/ports.tar [default]
-
Create the Portfile:
mkdir -p /Users/mforbes/src/ports/net/sshuttle curl https://raw.githubusercontent.com/macports/macports-ports/master/net/sshuttle/Portfile > /Users/mforbes/src/ports/net/sshuttle/Portfile
-
Edit the
Portfile
:#/Users/mforbes/src/ports/net/sshuttle/Portfile ... python.default_version 39 ...
-
Update the index:
cd /Users/mforbes/src/ports portindex
-
Update the port and clean:
port uninstall sshuttle # Get rid of old version port search sshuttle port install sshuttle port uninstall inactive port uninstall leaves port uninstall rleaves
Shell (bash)¶
Sometimes one might like to use another shell instead of /bin/bash
. For example, one might like to use the version /opt/local/bin/bash
provided by MacPorts so that one can use the bash-completion
package. To do this, we first install the shell, then enable it, finally we change the user shell:
port install bash-completion
sudo echo /opt/local/bin/bash >> /etc/shells
chsh -s /opt/local/bin/bash
mkdir -p ~/.local/share/bash-completion/completions
The for completions, I do things like:
poetry completions bash > ~/.local/share/bash-completion/completions/poetry.bash
Finally, in my ~/.bashrc
file, I have:
#~/.bashrc
...
if [ -f /opt/local/etc/profile.d/bash_completion.sh ]; then
. /opt/local/etc/profile.d/bash_completion.sh
fi
XCode¶
XCode is huge (~10GB), so I remove it (just drag XCode.app
to the trash) and just keep the command line tools installed:
xcode-select --install
After agreeing to the licence, you should see
$ xcode-select -p
/Library/Developer/CommandLineTools
Note: after you do this you will likely see the following warning from MacPorts:
* `Warning: xcodebuild exists but failed to execute`
* `Warning: All compilers are either blacklisted or unavailable; defaulting to first fallback option`
Conda¶
In install Conda with the following in mind:
- I use Miniconda as opposed to the full Anaconda distribution. If I need Anaconda, then I install it in a special environment.
- I install Conda as a special user
conda
so that I can't accidentally muck up the environments. This simulates what happens on HPC compute clusters etc. where we share conda environments. - Environments are specified with
environment.yml
files and Picky for Conda should be used to lock these. - Custom work should be done in a virtual environment that sits on one of these base conda environments.
Here is the complete setup process:
-
Create a
conda
user account. (Probably easiest just to use the GUI.) -
I was going to enable passwordless
su
access, but it seems easier just to enable anssh
alias:#~/.ssh/config ... Host conda_local User conda Host admin_local User admin Host *_local Hostname localhost ForwardAgent yes
Now copy the keys:
ssh-copy-id conda_local
-
Create the base environments:
sudo mkdir -p /data/apps/conda # Remove an old installation if needed sudo chown conda /data/apps/conda ssh conda mkdir -p zips cd ~/zips curl https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -O bash Miniconda3-latest-MacOSX-x86_64.sh -bfp /data/apps/conda /data/apps/conda/bin/conda init . ~/.bash_profile # Update the base environment with anaconda-client, then from my anaconda page: # https://anaconda.org/mforbes/base /data/apps/conda/bin/conda install anaconda-client -n base /data/apps/conda/bin/conda update -n base mforbes/base echo 'eval "$(mmf_setup -v -H)"' >> ~/.bash_profile # Added some bare python environments. I use these for testing with Nox. for py in 3.6 3.7 3.8 3.9; do /data/apps/conda/bin/conda create -y -c defaults --override-channels -n "py${py}" python=${py} done
-
Create some specialized environments. Ideally these should be able to be created from my anaconda channel:
ssh conda conda env update mforbes/jupyter conda env create mforbes/work
If you are updating them, it is useful to have them locally:
ssh conda mkdir -p repositories cd repositories hg clone ssh://git@hg.iscimath.org:11022/mforbes/configurations conda env create
Networking¶
To see your MAC address:
ifconfig en0 ether
If you need to change it, then you can spoof it with
sudo ifconfig en0 ether xx:xx:xx:xx:xx:xx
Note: make sure that en0
is the correct device. You might want to check the ouput of ifconfig
first to see that this is indeed the active device.
VPN¶
To connect to various services at WSU, I downloaded their Global Protect client. This is needed for some reason. In particular, without using the VPN, the following does not work:
(swan) $ nc -l 12345 # Start a netcat server listing on port 12345 on swan
then on my Mac:
(Rentdem) $ nc swan.physics.wsu.edu 12345 # Start a netcat client
Without VPN, I can only send about 4 messages in either direction, then the connection hangs. Not sure why.
Wireshark¶
Wireshark is a full-featured debugging tool for networks. I install it and add it to the PATH so I can use it in a terminal.
SSH¶
To tell KeyChain to remember your SSH keys do the following:
ssh-add -K [path/to/private SSH key]
SSHFS¶
You can use SSH to mount remote file systems locally with sshfs. On Mac OS X, do this by installing FUSE and the associated SSHFS package from that site. Once it is installed, you can mount a filesystem as follows:
mkdir -p ~/Volumes/swan
sshfs -o follow_symlinks swan:/ ~/Volumes/swan
To unmount:
umount ~/Volumes/swan
SSH Tunnels (SOCKS/VPN)¶
sshuttle user@host 0.0.0.0/0 -vv
This will forward all traffic through the specified host. See https://superuser.com/a/757974. sshuttle
can be installed with pip
or macports
.
BBCP¶
Related to SCP is bbcp
which can be downloaded for OS X here. This is a fast tool for transferring files. I just copy it to /usr/local/bin/bbcp
.
LaTeX¶
I install the MacTeX which puts most things in /usr/local/texlive
and also includes BibDesk, Skim etc. When you upgrade from one year to the next (say 2017 to 2018), the new installation will be placed in /usr/local/texlive/2018
leaving the old version in /usr/local/texlive/2017
. These can be big (~5.4GB) so you might want to move the old version off your hard-drive (but keep it for a bit in case things go wrong.)
Once you upgrade, you may need to make a few changes to keep things working, setting the path for the LaTeX programs. These should be set to
/Library/TeX/texbin
but might need to be updated. Check in the preferences of the following packages if things do not work as expected:
- BibDesk: (Seems okay with symlink above.)
- TeX Live: (Needed path refreshed as it seems to use the absolute path, but can refresh this for you if you confirm.)
- LaTeXiT: (Seems okay with symlinks.)
Safari¶
Extensions¶
-
Ad Blocking: There are several extensions that block ads.
- AdBlock: I have been using this and am reasonably happy with it. The blocking of ads in YouTube is especially valuable.
- AdBlock Plus: Another alternative that is almost the same (small UI differences).
- AdGuard for Safari: Was recommended in an uBlock issue about Safari. Does not block YouTube ads, but I have not tried the full AdGuard (just the browser extension).
For a comparison of the first two, see AdBlock vs AdBlock Plus.
-
StopTheMadness: Some websites disable useful features such as copy and paste. This extension claims to restore this functionality.
I used a different approach - temporarily disable JavaScript. This can be done under the Safari
Develop/Disable JavaScript
menu item, but I also enabled a shortcut ⌘J to Disable JavaScript..
Emacs¶
There are several options for using Emacs on Mac OS X:
-
GNU Emacs for Mac OS X: I use this. It is a fairly generic version of emacs with traditional key bindings. The only annoyance is that one must use Esc for the Meta key. (
M-x
is achieved by "pressing and releasingEsc
, then pressingx
.) - Aquamacs: This more tightly integrates with the OS X interface, but is significantly slower.
Configuration¶
I install the following packages using the Options/Manage Emacs Packages
menu option. Note, there are three main package archives. I use these with the following preference: 1) gnu
, 2) marmalade
, 3) melpa
(see this discussion for more details.
Editing Features
-
autopair
: Automagically pair braces and quotes like TextMate. -
org
: Outline-based notes management and organizer.
Modes:
-
auctex-latexmk
: Add LatexMk support to AUCTeX. -
haskell-mode
: A Haskell editing mode. -
lua-mode
: A major-mode for editing Lua scripts. -
markdown-mode+
: Extra functions for markdown-mode. -
markdown-preview-mode
: Markdown realtime preview minor mode. -
markdown-toc
: A simple TOC generator for markdown file. -
yaml-mode
: Major mode for editing YAML files
Elisp Debugging (init files)
-
benchmark-init
: Benchmarks Emacs require and load calls. -
bug-hunter
: Hunt down errors by bisecting elisp files. -
use-package
: A configuration macro for simplifying your.emacs
.
Git: (I don't really use these, but they were recommended at some point.)
-
git-commit-mode
: Major mode for editing git commit messages [github]. -
git-rebase-mode
: Major mode for editing git rebase files [github]. -
magit
: A Git porcelain inside Emacs.
Python: Modes for working with python.
-
conda
: Work with your conda environments -
python-mode
: Python major mode. This has some major problems when using Tramp for remote editing, so I do not use it any more. -
elpy
: Emacs Python Development Environment
Web/Blog:
-
sass-mode
: Major mode for editing Sass files. -
scss-mode
: Major mode for editing SCSS files. -
json-mode
: Major mode for editing JSON files. -
jinja2-mode
: A major mode for jinja2. -
tidy
: Interface to the HTML Tidy program.
I load these in my .emacs
file with the following code
;; Make sure required packages are installed
(setq package-list
'(use-package
autopair
org
auctex-latexmk
haskell-mode
lua-mode
markdown-mode+
markdown-preview-mode
markdown-toc
yaml-mode
benchmark-init
bug-hunter
use-package
;git-commit-mode
;git-rebase-mode
;magit
conda
;python-mode
elpy
sass-mode
scss-mode
json-mode
jinja2-mode
tidy))
;; list the repositories containing them
(setq package-archives
'(
("gnu" . "http://elpa.gnu.org/packages/")
("marmalade" . "http://marmalade-repo.org/packages/")
("melpa" . "http://melpa.milkbox.net/packages/")
;("elpa" . "http://tromey.com/elpa/")
))
;; activate all the packages (in particular autoloads)
(package-initialize)
;l fetch the list of packages available
(unless package-archive-contents
(package-refresh-contents))
;; install the missing packages
(dolist (package package-list)
(unless (package-installed-p package)
(package-install package)))
iPhone/iPad¶
Backups¶
If you make backups of your iPhone or iPad with iTunes, you can locate these with
-
iTunes/Preferences/Devices/Device Backups
and right-click toReveal in Finder
.
These files, however, are not organized and obfuscated. To interpret this data you seem to need to use a third party application. Most of these have a demo mode that will allow you to view the files, but put severe limitations on how much data you can actually extract without paying.
- iPhoneBackupViewer: View photos, but must save them one at a time. *
Useful Applications¶
GPG¶
This is useful for encryption and signing files. I use the vi plugin which allows you to edit encrypted files.
- https://gpgtools.org
-
https://www.vim.org/scripts/script.php?script_id=3645
Simply move the
gnugpg.vim
script into~.vim/plugin
:mkdir -P ~/.vim/plugin
Preference Panes¶
Vagrant¶
Docker/AWS-CLI¶
I don't really use Docker on my Mac, but install it so I can provision images on AWS. To do this I did the following:
-
Make a directory for installing the
aws-cli
without sudo:sudo mkdir /usr/local/aws-cli/ sudo chown mforbes /usr/local/aws-cli/
-
Download and install the
aws-cli
as a local user ("Install for Me Only").$ ln -s /usr/local/aws-cli/aws /usr/local/aws-cli/aws_completer /usr/local/bin/ $ aws --version aws-cli/2.1.10 Python/3.7.4 Darwin/18.7.0 exe/x86_64 prompt/off
-
Install the Docker App for OS X. Note: I though I could use
port install docker docker-machine
and save on some disk space, but this needs Vagrant, so no clear savings there. There are some relevant discussions in this direction though:
Disk Space:¶
Docker uses lots of space. Some can be reclaimed with:
docker images
docker rmi <images>
docker system prune
docker run --privileged --pid=host docker/desktop-reclaim-space
Environment Modules (Lmod)¶
To maintain some coherence with HPC environments, we install some version of the Environment Modules package. Here we use the Lmod variant as this is used on our local cluster.
luarocks install luaposix
luarocks install luafilesystem
LUAROCKS_PREFIX=/opt/local/share/luarocks
export LUA_PATH="$LUAROCKS_PREFIX/share/lua/5.3/?.lua;$LUAROCKS_PREFIX/share/lua/5.3/?/init.lua;;"
export LUA_CPATH="$LUAROCKS_PREFIX/lib/lua/5.3/?.so;;"
APP="Lmod"
VER="8.4"
NAME="${APP}-${VER}"
FILE="${NAME}".tar.bz2
cd ~/zips/
wget https://sourceforge.net/projects/lmod/files/"${FILE}"
cd ~/src/
tar -jxvf ~/zips/"${FILE}"
cd "${NAME}"
./configure --prefix=/data/apps/
make install
I then added the following (from Environment Modules):
cat << EOF > /data/apps/lmod/lmod/modulefiles/Core/use.own
#%Module1.0#####################################################################
##
## use.own modulefile
##
proc ModulesHelp { } {
puts stderr "\tThis module file will add \$HOME/privatemodules to the"
puts stderr "\tlist of directories that the module command will search"
puts stderr "\tfor modules. Place your own module files here."
puts stderr "\tThis module, when loaded, will create this directory"
puts stderr "\tif necessary."
}
module-whatis "adds your own modulefiles directory to MODULEPATH"
eval set [ array get env HOME ]
set ownmoddir $HOME/privatemodules
# create directory if necessary
if [ module-info mode load ] {
if { ! [ file exists $ownmoddir ] } {
file mkdir $ownmoddir
set null [open $ownmoddir/null w]
puts $null "#%Module########################################################################"
puts $null "##"
puts $null "## null modulefile"
puts $null "##"
puts $null "proc ModulesHelp { } {"
puts $null " puts stderr \"\tThis module does absolutely nothing.\""
puts $null " puts stderr \"\tIt's meant simply as a place holder in your\""
puts $null " puts stderr \"\tdot file initialization.\""
puts $null "}"
puts $null ""
puts $null "module-whatis \"does absolutely nothing\""
}
}
module use --append $ownmoddir
EOF
To use these, I add the following to my ~/.environment_site
file:
# Site specific bash environment init file; -*-Shell-script-*-
# dest = ~/.environment_site #### Keep this as the 2nd line for mmf_init_setup
# This file is loaded by .environment and should be used to set the
# environment for site-specific customizations
...
test -f "/data/apps/lmod/lmod/init/profile" \
&& . "/data/apps/lmod/lmod/init/profile"
...
# Load useful modules.
module load use.own cuda git-annex node mongodb fftw # anaconda
For details about what these do, see my modules configurations folder.
Graphics¶
Julia¶
Some tools - in particular the diffeq library - use Julia, but it is not so easy to install via Conda. I install the native application. After installing I had to link it:
ln -s /Applications/Julia-1.5.app/Contents/Resources/julia/bin/julia ~/.local/bin/
conda activate jupyter
export JUPYTER="$(type -p jupyter)"
julia
Then, using julia:
using Pkg
Pkg.add("IJulia")
Pkg.build("IJulia")
Note: If this fails, you might need to manually clone the registry:
git clone https://github.com/JuliaRegistries/General.git ~/.julia/registries/General
Then, in python, I needed to:
conda activate work
pip install diffeqpy
python -c "import diffeq;diffeq.install()"
This installed everything needed into ~/.julia
.
References¶
Sound: Black Hole¶
I used to use SoundFlower to route audio on my Mac. This is no longer supported, but they recommend Loopback. Another option is BlackHole as discussed in this article. JACK is another option (this is used by Audacity – a great open-source tool for editing audio.)
Sim Datlonism¶
Color-blind simulator. Useful for checking graphs, posters, etc.
Microsoft Office¶
I have the problem of running with fairly limited disk space, so installing the complete Office suite was prohibitive. For a long time I stuck with Microsoft Word for Mac 2011, which I got from the department. It appears now that individual apps are available through the App Store: