Expand Tilde Paths in Bash and Python

Sometimes it’s necessary to reference files in a script using ~. For example, if you want to schedule a cron job to run a script in a folder and place the results in the same folder, it’s helpful to use absolute referencing of the files in the script.

Bash

Here’s my first attempt to append to a file:

$ ./my_folder/run.sh >> "~/my_folder/output.txt"
-bash: ~/my_folder/output.txt: No such file or directory

The issue with the above line is that the ~ is not expanded to the home directory (such as /home/username/) because it is inside the quotes. To fix this, move the path outside of the quotes, but leave the filename in single quotes (to escape the . in the extension):

$ ./my_folder/run.sh >> ~/my_folder/'output.txt'

Python

I encountered a similar issue in Python:

>>> with open('~/my_folder/output.txt', 'r') as f:
...   contents = f.read()
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
FileNotFoundError: [Errno 2] No such file or directory: '~/my_folder/output.txt'

This can be fixed using os.path.expanduser(path):

>>> import os
>>> filename = os.path.expanduser('~/my_folder/output.txt')
>>> with open(filename, 'r') as f:
...   contents = f.read()
...
>>> print(contents)
10

iPad Screenshots

Dr. Drang:

On the iPad, ⇧⌘3 captures the whole screen, just like the Mac (and just like capturing with the top and volume up buttons). The ⇧⌘4 shortcut also captures the whole screen, but in a neat analogy to the Mac, it immediately puts you into editing mode so you can crop the capture down to a smaller size.

I don’t find these keyboard shortcuts surprising, but it is surprising that I never thought to try it on an iPad. With the new screenshot tool in macOS Mojave, I wonder what other features will reach parity on macOS and iOS in the future.

Removing Local Git Branches That Aren't 'master'

Every so often, I’ll want to delete all of my local branches for a repository that aren’t the master branch. An easy command to do this is:

$ git branch | grep -v "master" | xargs git branch -d

(If you want to keep multiple branches, such as master and develop, you can chain them together using grep -v "master\|develop")

git branch lists all of the local branches for the repo, grep -v prints all of the lines from the previous command that don’t match “master”, and xargs takes each line from the previous output and runs git branch -d <output_line>.

I recommend using -d rather than -D in case git recommends not deleting the branch.