Category Archives:MacOS/*BSD
macOS/OS X, FreeBSD/OpenBSD/NetBSD
Automatically Conceal Sender’s IP Address in Email Clients via SSH Tunneling
Last updated on May 5, 2021
Desktop email clients, such asThunderbird andClaws Mail, are preferred over their web counterparts by many professionals and power users due to their additional convenience and security. However, one big downside is that they often expose the sender's IP address to the receivers, since many SMTP servers record the sender's IP address and put it in the header, something similar toReceived: from [xxx.xxx.xxx.xxx] (my.example.com. [xxx.xxx.xxx.xxx])
. This, unfortunately, puts the sender's privacy in great jeopardy, as an IP address can reveal so much information including location, ISP, and institution names.
To address this issue, one simple solution is to let the email client connect via a proxy. While a system-widely available proxy works for many users, some of us just want our email clients, but not other programs, to go through a specific proxy. In this post, I'll demonstrate how to use an email client automatically via SSH tunneling. The instructions are specifically tailored for GNU/Linux and MacOS users, as it involves some uses of UNIX commands and bash scripts; if you are on Windows, you can still follow the instructions with the help ofCygwin.
Enable Auto Completion forpip
in Zsh
Last updated on August 8, 2017
Pip is a package management system for installing and managing Python software packages. To enable auto completion forpip
in zsh, thedocumentation of pip suggests adding the following line to~/.zshrc
:
eval "`pip completion --zsh`"
However, merely having this line would not enable auto completion forpip3
. To enable auto completion forpip3
as well, add the following line after the line above:
compctl -K _pip_completion pip3
Enable Natural Scrolling for Trackpads Using libinput
Last updated on October 28, 2018
Libinput is a library to handle input devices inWayland andX.Org. It can be used as a drop-in replacement for evdev and synaptics in X.Org, and it is supported by a wide range of desktop environments, including GNOME and Xfce. In this post, we will see how to enable natural scrolling for trackpads using libinput. We will also leave mouses alone, i.e., no natural scrolling for mouses.
First, we need to know the name of the trackpad to enable natural scrolling for. This can be easily known by executingxinput --list
. My output includes the following:
⎡ Virtual core pointer id=2 [master pointer (3)]⎜ ↳ Virtual core XTEST pointer id=4 [slave pointer (2)]⎜ ↳ bcm5974 id=13 [slave pointer (2)]
It is easy to see that my trackpad isbcm5974
.
Parallelizemake
by Default
Last updated on December 13, 2016
Themake utility is an standard utility on POSIX systems (GNU/Linux, macOS, etc.) that update files derived from other files, such as compiling source files to their binary forms. It is widely supported and used across different fields such as organizing and building C/C++/Fortran projects, buildingSphinx documentation, etc.
The most popular implementation of the make utility is probablyGNU make, which is usually the default make program on various GNU/Linux distributions. (On macOS, the version of the default GNU make is pretty old. Please consultInstall and Use GNU Command Line Tools on macOS/OS X for a newer version.) It adds one very important feature besides the standard make specification: parallelization. The command line option-j
can be used to specify the maximum number of jobs that it is allowed to run simultaneously. However, it is quite annoying to type up this option every time when using it—we want a setting such that the CPU can be fully utilized by default. To achieve this goal, add the following lines to your~/.bashrc
if you use bash or~/.zshrc
if you use zsh:
# set MAKEFLAGSif type nproc &>/dev/null; then # GNU/Linux export MAKEFLAGS="$MAKEFLAGS -j$(($(nproc)-1))"elif type sysctl -n hw.ncpu &>/dev/null; then # macOS, FreeBSD export MAKEFLAGS="$MAKEFLAGS -j$(($(sysctl -n hw.ncpu)-1))"fi
The code above sets the envrionmental variableMAKEFLAGS
, which specifies the command line arguments of any invoked make subprocesses. It is set such that the maximum number of jobs that is allowed to be run simultaneously is equal to the number of available CPU cores minus 1. In this way, the hardware is more or less fully utilized when using make, with one CPU core left for other potential tasks on the system.
A Betterls
Command
Last updated on April 14, 2024
Thels
command is a command to list files on a UNIX-like system. It is probably one of the most used command. However, a plainls
command without any polishing may look really “plain”. Here, we will slightly configure this command to make it more usable:
- More colorful output
- Automatic pagination for long file lists
- File type indication
- Human readable sizes
- Natural ordering of files
Screenshots:

Output ofls
before configuration

Output ofls
after configuration

Pagination forls
Speed Test: Check the Existence of a Command in Bash and Zsh
Last updated on December 10, 2016
In both bash and zsh, there are multiple methods to check whether a command exists. In this post, a set of speed tests will be performed on them to find the fastest way in each of the two shells (NOT to compare the two shells). We will test 5 different methods (foobar
is the command to test for existence in the list):
type foobar &> /dev/null
hash foobar &> /dev/null
command -v foobar &> /dev/null
which foobar &> /dev/null
(( $+commands[foobar] ))
(zsh only)
All the methods listed above will have a return status of zero if the commandfoobar
exists, otherwise non-zero. That is, after replacingtesting-command
by any of the commands listed above, you can test the existence of the commandfoobar
by executingtesting-command && echo exist || echo non-exist
.
Throughout this post,ls
will be the command that is used for testing existence, which does exist on the system which runs the tests. The test environment is Debian Jessie with bash 4.3.30 and zsh 5.0.7 on Intel Xeon processor E3-1240 v3 (8 MB Cache, 3.4 GHz). The test scripts are also available at the end of the post.
Restore the Previously Canceled Command in Zsh
Last updated on December 10, 2016
Inzsh, it is often annoying that we can't easily restore the command we just canceled byCtrl-C: canceled commands are not recorded into the history file and thus cannot be restored by searching previous commands. To make the restoration possible, zsh provides a variableZLE_LINE_ABORTED
which keeps a record of the last command that was canceled—everything looks so simple. However, for some reasons, such as canceling stuck tab completion, we often pushCtrl-C for more than once—butZLE_LINE_ABORTED
would become empty ifCtrl-C is used on an empty line! Thanks to the great extensibility of zsh, we can solve this issue by tweakingzle-line-init
(add the following to your~/.zshrc
):
function zle-line-init { # Your other zle-line-init configuration ... # Store the last non-empty aborted line in MY_LINE_ABORTED if [[ -n $ZLE_LINE_ABORTED ]]; then MY_LINE_ABORTED="$ZLE_LINE_ABORTED" fi # Restore aborted line on the first undo. if [[ -n $MY_LINE_ABORTED ]]; then local savebuf="$BUFFER" savecur="$CURSOR" BUFFER="$MY_LINE_ABORTED" CURSOR="$#BUFFER" zle split-undo BUFFER="$savebuf" CURSOR="$savecur" fi}zle -N zle-line-init
- Line 1: Define the
zle-line-init
widget which will be executed every time when the a new command line is ready to take input. - Line 5-7: If
ZLE_LINE_ABORTED
is non-empty, save it toMY_LINE_ABORTED
. - Line 10-16: If
MY_LINE_ABORTED
is non-empty, the initial undo will restore the contents inMY_LINE_ABORTED
. Also seeman zshzle
for an explanation ofsplit-undo
. - Line 18: Install the widget
zle-line-init
.
Now type any command and pushCtrl-C twice and undo (bound toCtrl-/ by default): your canceled command is back!
Note that if you usezsh-autosuggestions
this code snippet somehow breaks it. Adding_zsh_autosuggest_widget_clear
before the end ofzle-line-init
would fix it.
References
Make theless
Command More Powerful
Last updated on December 25, 2024
Due to its speed and simplicity,GNUless
is probably the most common defaultterminal pager on various GNU/Linux distributions—you may have probably used it explicitly via theless
command, or implicitly when you execute theman
command orgit diff
. Although the default configuration ofless
does not really offer much except for a basic text viewer, it is actually much more powerful than most people think. Here a few improvements over the default configuration are offered.
For macOS/OS X users: consider installing a newer version ofless
and other GNU command line utilities. To do so, you can follow the instructionshere.
Truncate Long Matching Lines of Grep: a Solution That Preserves Color
Last updated on December 10, 2016
It is well known that long matching lines returned by grep is often disturbing. For example, a simple grep on a bootstrap javascript filebootstrap.min.js can cause a crazy tragedy—one single matching line can occupy a number of lines in the terminal:
How can we solve this issue?
Back up (Migrate) Homebrew Packages
Last updated on October 9, 2016
As one of the most popular package manager on OS X,Homebrew is indeed a very nice tool to manage packages. However, when you want to back up your packages, or migrate the packages onto another machine, Homebrew didn’t invent such a tool. If you are moving to an OS X of the same version, you can simply copy the Homebrew directory (default is/usr/local
) to your new machine. Otherwise, we need to find a way to install the exactly same packages on your new machine. In order to accomplish the goal, I wrote a small piece of bash script to generate a restore script to install the packages.