If you are a moderate to heavy user of the command line in Linux or OS X, you’ll eventually build up a set of custom commands and shortcuts that you’ve written that help streamline your workflow. These are known as “aliases.”
Let’s say you frequently find yourself searching your shell history for a command you used before.
To display your command history, you simply type `history`in your shell, and every command you’ve typed streams by.
This is useful, of course, but most likely you want to know about a particular command you typed, so you might use shell redirection to pipe the output to another command, in this case, `grep` to find lines in history that are interesting to you. In this example, we’re looking for commands we’ve typed that involved the word “projects”:
$ history | grep projects
9627 cd projects/ansible_dexter
9641 cd ~/projects/ansible_dexter
9675 cd projects/ansible_dexter
9684 cd ~/projects/sendgrid-test
9696 source /home/jim/projects/sns_python/venv/bin/activate
9707 source /home/jim/projects/sns_python/venv/bin/activate
9713 cd ~/projects/
9863 cp -r ~/projects/sendgrid-test/lib64 .
9865 cp -r ~/projects/sendgrid-test/share .
9962 cd projects
9972 cd projects/terraform-provider-aws
9979 cd projects/terraform-provider-aws
10003 cd projects/terraform-provider-aws

For me, this is something I do so frequently that I wanted to shorten that command to the minimum number of characters. I settled upon `hg` for “history grep”, so I created an alias as a line in my `~/.zshrc` file: `alias hg=”history | grep”`
The `~/.zshrc` (or `~/.bashrc` if you use `bash` as your shell,) is a file that gets read every time you log in and sets up your preferred environment.
Perfect! Now, if I want to search history for commands that included a particular string, I can just type `hg projects` and I will get the above output.
Well, nearly perfect…

As it happens, hg is also a command used by the Mercurial Source Code Management system. This is not a big issue for me, as I’m a loyal Git user, but it presents an interesting dilemma:

How do I protect against command name collisions in my aliases?

You see, pretty much any alias you create has the potential to conflict with a command someone else has written, but where this gets even more complicated is when these commands are referenced from a script. Scripts should, however, only call external programs using the program’s full path, e.g.:/bin/ls instead of just ls
A blog post by Brandon Rhodes proposes an interesting solution:
Prepend all of your custom commands and aliases with a comma. Interestingly, a comma is just a normal letter to the shell, no different than renaming your command jimoconnell_hg, though a comma is of course much shorter.

(This post is meant not only to describe a little shell function, but to introduce you to a powerful, yet simple concept.)

When I’m working with a command line, I will frequently need to create a directory and then immediately change to that directory.

Let’s say I’m starting a new project. I will cd into my ~/projects directory and then create a new folder where I’ll be putting my files. After creating the new folder, I’ll generally need to `cd` to that folder.
cd ~/projects
mkdir foo
cd foo

My first thought was to write a little `alias` that combined the two operations, but aliases don’t really handle parameters well, so I wrote it as a shell function. (I use the amazing `zsh` as my terminal shell, but this approach works just the same in bash.)
In the below example, the “$1” refers to the argument passed. “$2”, “$3” and so on also work. (Be sure to quote them!)
mgo () {
mkdir "$1"
cd "$1"
}
You can paste that into your shell and it will work for the duration of your session, but of course the better way of making it available is to put it in your `~/.zshrc` or whatever your ~/.profile file is in your shell of choice. For example, in OS X, you have to first create the file:

Start up Terminal.
Type "cd ~/" to go to your home folder.
Type "touch .bash_profile" to create your new file.
Edit .bash_profile with your favorite editor (or you can just type "open -e .bash_profile" to open it in TextEdit.

To use it, you need to have that file be re-read, so you can either close and re-open your terminal, `source` the file you just edited, or just paste the function in to have it be active for the current session.

I realize that this is an insanely simple thing to worry over, but so much of the Linux/Unix philosophy is about making things just a bit more efficient and shell functions are a very approachable way to craft your own customizations for efficiency.

Another Example:
If you’re a python programmer or student, you are probably aware of venv, the virtual environment for Python that create lightweight Virtual Environment on a directory-by-directory basis. If you have, you know that each time you move to a project directory, you need to type `./venv/bin/activate` to set up the environment. A clever function I found a while back takes over the `cd` command to check for a virtual environment and activate it if it exists:cd () {
builtin cd $1
if [[ -d ./venv/bin ]]
then
source ./venv/bin/activate
fi
if [[ -d ./bin ]]
then
source ./bin/activate
fi
}
Both of the above examples are simple, but useful. Please leave a comment below if you know of any other good examples, or can think of a good use case for a function.

The other day I was writing about a method for Proximity Presence Detection using a Raspberry Pi and the Bluetooth radio in your smartphone.

(Basically, when your phone (or other Bluetooth device) gets within range of the Raspberry Pi’s Bluetooth, the MAC Address of the phone is noted and a script sends some data to an MQTT server, so you can determine with some confidence that you are home. It’s quick, lightweight and doesn’t require any software to be installed on the phone. Once the script notes your presence, you can do things such as turn on lights, have your home automation system greet you or do pretty much anything that computers can do.)

While setting it up, I noticed something odd, though–turning off Bluetooth didn’t really turn off Bluetooth, at least on my iPhone.

Here’s what I expected to see. The number in bold, right after “confidence” is the value that shows that the radio is active within range. When it disappears from range, the number tapers down over a period of 90 seconds or so:

My first suspicion was that my installation of the script was at fault or that perhaps I was reading the wrong MAC address, but I checked those and quickly started to suspect my phone.To test this, I shut off my phone and saw the confidence percentage drop gracefully to zero. I turned the phone back on and the script performed perfectly, detecting the radio instantly.

(“Airplane Mode,” I found, did actually turn off the radio, as you would expect.)

Next, I connected a Bluetooth speaker and started playing music, while watching my script. Hitting the Control Center icon disconnected the speaker, but didn’t shut off the radio.

This struck me as odd behavior, but not surprising, given that it’s Apple and I have little confidence in them to be upfront about something like this.

I dug around a bit this morning and came across an Apple support article titled “Use Bluetooth and Wi-Fi in Control Center with iOS 11 and later.” In that rather vaguely titled article, it says the following:

In iOS 11 and later, when you toggle the Wi-Fi or Bluetooth buttons in Control Center, your device immediately disconnects from Wi-Fi and Bluetooth accessories. Both Wi-Fi and Bluetooth will continue to be available, so you can use these important features:

Not in the list, but according to another source, Apple’s AirPod earphones apparently also do not disconnect when Bluetooth is deactivated from Control Center. (I have no AirPods to test this.)

Also worthy of note is that if you do it this way, it will automatically restore Bluetooth to full capacity the next day at 5:00 AM local time. Why it does this isn’t clear, but it’s probably so your Bluetooth alarm clock will still function or something.

If you go into IOS’s “Settings” app, you the Bluetooth controls behave as you would expect–turning off Bluetooth actually does shut off the radio, so I doubt this is anything beyond Apple making their own proprietary technologies and accessories work better than third-party stuff.

Anyway, I thought it was interesting enough to dig into a bit and share with you all.

The big takeaway is that using Control Center is not the same as controlling things via the Settings app and may not behave as expected.

If you do much of anything using a Linux terminal, you really owe it to yourself to take a look at Byobu, which is, according to Wikipedia, “an enhancement for the GNU Screen terminal multiplexer or tmux used with the GNU/Linux computer operating system that can be used to provide on-screen notification or status, and tabbed multi-window management. It is intended to improve terminal sessions when users connect to remote servers. “

This is one of the first things I install on any of my Linux boxes.

Watch the video for a bit–it’s a bit like watching a master chef slice and dice vegetables.

What it does is run a script as a service on the Pi and watches for a pre-defined list of MAC addresses to enter its Bluetooth radio’s range. It sends out statuses on that MAC address to an MQTT server running on the Pi or elsewhere. The messages each look something like this:

The first part of that is the MQTT topic (with my MAC address obscured): home/bedroom/E4:E4:ZZ:00:XX:XX

Next is a bit of JSON that tells you the script’s “confidence” that the device is home, as well as the name of the device:{"confidence":"100","name":"Jim’s iPhone" …}

There are several things that make this strategy particularly cool.The first is that once it’s in MQTT, you can use this piece of information in any number of ways, the most obvious one being a Home Automation system such as Home Assistant or Domoticz. It would be trivial to whip up a script with Python and its paho-mqttlibraries, for example.

Another reason is that it doesn’t require any special software to be running on the phone–the Bluetooth radio broadcasts everything you need by default.

What all this gives you is a way to detect when your phone (you) comes within about 30 feet of a Raspberry Pi or even the $10 Raspberry Pi Zero. This is ideal for, say, turning on some lights when you pull into the driveway, (but perhaps not for unlocking an automatic door.)I’ve only tried it with my iPhone, but in theory, you could do this with any Bluetooth device. It should even work with something like a Tile, the key-finding gizmo, something that would be of great interest. (I just need to figure a way to retrieve the MAC address from the Tile.)

Neat stuff. So far, I like this better than other solutions I’ve found for presence detection.

Finally, something unexpected:

When I was setting this up and testing it, I noticed something unusual. To turn off Bluetooth on my iPhone, I would open this panel and tap the Bluetooth icon:

The odd thing is that when I did that, the Presence software would still see the iPhone as being nearby. Tapping “Airplane Mode” would actually turn off the Bluetooth radio and the script would see it as gone.

Note: This is probably only of use to those using “Unix-like” systems such as OS X and Linux. It may or may not work on Windows, using Git Bash. Probably not useful on Windows, otherwise.

In this post, we’ll be covering a few things. First up is the concept of “dotfiles,” the configuration files you keep in your home directory that provide customization and configuration.

After that, we’ll take a look at some strategies for maintaining these configuration files using Git, the version control package that powers the Open Source movement.

Finally, we’ll be looking at so-called “bare” repositories as well as some clever tweaks that you’ll be able to apply not only to your dotfiles, but to anywhere you might want to leverage Git for files that may not live inside a traditional repository.

First up, the Dotfiles

On a Unix/Linux system, when you don’t want to see a file by default, you can hide it from view by starting its filename with a “dot,” or period character. This is a convenience, not a security measure–it’s a way of keeping your view of a directory relatively uncluttered.

For example, if I take a look at my home directory using ls, here’s what I see:

There are both dot files and dot folders in that list. (Hiding a directory is done the same way, just prepend its name with a dot.)

Many of these are configuration files and directories, especially for command line utilities. The Files .zshrc and .zsh_history and the folder .oh-my-zsh for example, are the configuration files that hold all of my customization directives for ZSH, the shell I use, as well as the incredible Oh My Zsh.

To edit files, I use Vim, also with a ton of customizations found in the files .vimrc, .viminfo and the directory .vim

These files are what make your working environment your own. When you’ve gotten them just how you like, you don’t want to lose them, or have them get out of sync with other machines you may work on. It makes sense to keep them in a structured version control system.

Git to the rescue.

If you’re reading this, you’re probably familiar with Git. You may have cloned a repository from github.com or even created and shared repositories of your own. Typically, you’ll clone a project, which will exist as a directory filled with source code that you’ll edit or compile or whatever. When you make changes, you can commit them back up to Github or BitBucket, or somewhere else. Git’s great–you can work with highly distributed teams of collaborators or work offline. You can, (if you’ve set it up correctly,) jump back to any save point and step through every commit.When you’re a single user, you can use it to sync your project across many machines, which makes it ideal for synchronizing your dotfiles. What always stopped me from doing this is that I didn’t want to put my whole home directory into Git – there’s a lot of stuff I don’t want to sync and the only way I knew how to exclude it was by explicitly listing it in the “Git Ignore” file, which seemed like too much work.What some people started doing was to create a git repo, one level down, that contained the files, along with a script that would create symbolic links from that directory to your home directory. To me, this seemed an inelegant solution.

An Elegant Solution

A while back, I decided to revisit the problem and did some Googling, eventually coming across a post on Ycombinator:

This part is really, really cool–it creates a new command called config that you use just like the command git, that adds some special options that apply only to the dotfiles problem.It’s a wrapper for Git that says that the working directory is in ~/.myconf, but the actual versioned files live in your home directory.Read that a couple times until you completely understand the sheer awesome power of what that simple line does. Elegant AF.

The last line uses our newly-minted command to tell git to ignore files that we haven’t explicitly added, something that makes a lot of sense, given how much junk gets stashed in $HOME:config config status.showUntrackedFiles no

Anyway, what was supposed to be a quick post has grown a bit, so I’m going to go ahead and publish it. Let me know if you have any questions or see any errors.

Please note! Your .ssh directory is kind of special in that while you may want to back up your encryption keys, doing so on a site such as Github is a tremendously bad idea. Just don’t. Feel free to back up .ssh/config though, if you’ve customized it.

Reading Time: 1minuteI’ve been working on a side project lately that, while isn’t anywhere near completion, is probably ready to start sharing.
It’s a course, of sorts, that I’ve been calling “Everything but the Code.” When I get a feel for how much time each section will take, I’ll begin the process of finding students for a face-to-face class.

It’s an introduction to some of the technologies I use that aren’t programming, but are all tools in a programmer’s tool box. Things like Unix and ‘Unix-like’ filesystems, Unix-like command interpreters, (AKA, “Shells,”) Git and GitHub–stuff that’s pretty much assumed that you know how to do, yet so many good programmers don’t.

Introduction

In this post, we’re going to be taking a look at sorting, with a particular focus on what’s known as a “Bubble Sort.”

Sorting

In computing, sorting is one of those things you rarely think about. Applications that present users with lists usually have a button to sort search results. Your Amazon or eBay searches let you sort by price or distance, for example.

Linux has a handy commandline utility called ‘sort’. Let’s say you wanted to know about a certain subset of programs you were running and you started with:

$ ps aux |grep $USER

which dumps a whole lot of information to the screen, so you start piping that through other utilities, (often called ‘filters’ when used this way,) until you come up with something like this:

(Note: This is not a useful set of filters. I just cobbed it together as an example)
It works and works well, without us having to think about how a computer performs the many, many operations needed to actually do the sort.
There are many algorithms, in many different languages and perhaps the simplest is known as a Bubble Sort.

So, what’s a Bubble Sort?

A “Bubble Sort” is an algorithm where the desired results “bubble up,” based upon the comparisons you do to pairs of elements, as you iterate through a stack of numbers. Basically, you step through your array and compare each value with the adjoining value. If it’s lower, move it to the left. Keep iterating until your array is sorted:
Gary Sims, from the excellent Gary Explains channel on Youtube explains it really well here:
(If you want to play with Gary’s code, but don’t feel like typing it in, you can grab it from my Github copy of it:

$ git clone https://github.com/jimoconnell/BubbleSortSaga.git

This is really a great way to understand what happens in a bubble sort, but of course, written in python, it’s probably only useful as an educational exercise. Python, after all, is a very high level language.
Take a look at this example, written in Assembler, a very low-level computer language that’s as close to machine code as anyone is likely to be working with:
(Example code by @stephenpaulger on GitHub)

Even if you’ve never looked at Assembler before, with the comments, it’s not difficult to see what’s going on and that it’s not too different than Gary’s Python example.

This is all something that you could do with playing cards: take eight or so number cards from the deck and arrange them in random order, face up. Take the first two cards and compare them. If the card on the right is the lower of the two, swap the two cards. Move one spot to the right and repeat. Do this for the whole row. When you get to the far right, start again from the left and repeat the process, until you have no more cards to swap.

I hope that gives you a better understanding of one of those basic concepts that are too-often neglected in computer education.

Reading Time: 4minutesToday’s article is an introduction to the ‘tldr’ utility, a collection of simplified and community-driven man pages. ‘tldr’ enhances Unix/Linux by providing clear, real-world examples for using command line utilities.

When I was a kid, I had the kind of parents who would never tell you the meaning of a word.
“Get the dictionary and look it up,” I was told over and over.
It was good for me, of course, as a learning exercise, but at the time, it seemed almost punitive.
“Ugh, do I haaaave to? Can’t you just tell me??”

Well, if you’re like me, that’s how it feels to work with Unix “man’ pages–you know that all the answers to your questions are in there, somewhere, but the compilers of the pages seem to have forsaken readability for completeness and uniformity.
That doesn’t help, when some commands are notoriously hard to remember:

Unix ‘man’ pages have been around since 1971, first written by Dennis Ritchie and Ken Thompson, the most venerated names in Unix. They are necessary and thorough, don’t get me wrong. I have nothing but respect for them. It’s just that, well, once in a while, they were a bit more, readable and perhaps, concise. For example, here’s (a bit of) what ‘man’ has to say about the ‘ls’ command:

$ man ls
LS(1) User Commands LS(1)

NAME
ls – list directory contents

SYNOPSIS
ls [OPTION]… [FILE]…

DESCRIPTION
List information about the FILEs (the current directory by default). Sort entries alphabetically if none of -cftuvSUX nor –sort is specified.

Mandatory arguments to long options are mandatory for short options too.

-c with -lt: sort by, and show, ctime (time of last modification of file status information); with -l: show ctime and sort by name; otherwise: sort by ctime, newest first

(That’s just the start. It goes on for a total of 206 lines on my system.)
Reading that feels a bit like taking that long walk to the bookshelf to open the dictionary, only to be overwhelmed with seemingly irrelevant information, when the information you actually needed could have been cleared up with an example or two. (Again, I’m not advocating the dumbing down of the ‘man’ page system–it’s comprehensive, as it needs to be. It’s just that there’s room for something more, especially as more and more casual users discover Linux.)

ls is one of the simplest commands in the *nix shell. Essentially, it lists out the contents of a directory. You can run it by itself:

$ ls
bar baz corge foo quux quuz qux

That will list out the names of the non-hidden files in a directory. If you want to see the hidden files, you add the ‘-a’ option:

$ ls -a
. .. bar baz corge foo .hidden_file quux quuz qux

If you want to list out pretty much everything, add a bunch more options, that spell out “-Flag” (That’s 4 options, ‘F’, ‘l’, ‘a’ and ‘g’, not a word. ‘galF’ would work as well, but ‘Flag’ is easier to remember.):

That was even easier than Googling stackoverflow. (Of course, if you were to *ask* on stackoverflow something as simple as options for ‘ls’, you’d immediately get sent to the ‘man’ pages.) Fortunately, there are places to go for questions like this.

If you’re not ready to install tldr on your own system yet, you can always use the online version.

I hope this has been helpful. I only found out about ‘tldr’ this morning, as it was linked to from a post on Reddit and wanted to share it with you all.