Chris Hannah

Command Line

Interesting macOS Command Line Tools #

I just came across this great list of command line tools for macOS by Saurabh, and to be honest, I had never heard of quite a few of them.

For example, who knew about textutil that can convert text documents between types like txt, html, docx, etc?

Or also a tool like networkQuality that can measure your internet speed? It even gives you a great readable output like this:

Downlink: capacity 105.573 Mbps, responsiveness 64 RPM - Uplink: capacity 6.886
Downlink: capacity 103.467 Mbps, responsiveness 64 RPM - Uplink: capacity 6.880
Downlink: capacity 100.457 Mbps, responsiveness 64 RPM - Uplink: capacity 6.890
[...]
==== SUMMARY ====
Uplink capacity: 8.511 Mbps
Downlink capacity: 20.053 Mbps
Responsiveness: Low (67 RPM)
Idle Latency: 36.917 milliseconds

If you use the command line at all on your Mac, I recommend at least giving this list a once over.


A Better Git Command Line Experience #

I’ll start by saying that I’m the sort of person that prefers to use the command line for Git commands. But there are still occasions where I just found it annoying, such as managing huge amounts of branches, reading old diffs, and also when making a big commit, and wanting to get a quick overview of what’s being added.

For those occasions, I used Fork. Although I’m sure for my uses, I could have probably used any Git GUI. However, I’m now using a terminal UI called Lazygit. I think it’s incredible. It lets me stay in the terminal, but gives me the functionality (that I use) of a typical GUI app.

This is what it looks like:

Because it’s a terminal app, it’s full of keyboard shortcuts, that make everything super fast. For example, to pull changes, you just use a lowercase p, and to push it’s an uppercase P.

Most of them are that simple that you just tap one key, but they tend to be limited to the active panel. For example, if you want to manage branches, then the branches panel needs to be the active one. Once it’s active, you can use things like space to checkout the selected branch, n to create a new branch, d to delete, o to create a pull request, etc. There’s honestly so many that if you were to check out Lazygit, I’d recommend having a glance at the full list of key bindings.

This is obviously a small example, but here is the experience of committing files:

It’s not limited to the keyboard though, you can navigate Lazygit using the cursor as well:

After installing Lazygit, I haven’t needed to use a GUI application at all. I know some may prefer to use a GUI, but I certainly have found Lazygit so much easier to use. Especially because of the abundance of keyboard shortcuts, and also because it lets me keep my Git activity to a single terminal window.

Lazygit works everywhere, macOS, Linux, or Windows, so if you want to enhance your Git experience in the command line, I’d definitely recommend checking it out.


A Few Things I Use the Command Line For #

I’ve noticed myself using the command line a lot more recently, at home, and work, so I thought I’d share a few of the little tools and handy commands that I use on a day to day basis.

Note: I use ZSH as my shell, with oh my zsh, so they may differ slightly if you’re using something different.

Aliases

The most helpful commands that I use have to be aliases for the most minor commands. But because they’re used so often, it saves so much time.

The majority of them are for two things - moving to common directories, and launching applications.

Here are a few examples of directories I have set up with aliases:

  • h: home directory
  • dev: developer directory where I store all projects
  • tc: Text Case directory
  • blb: Bulba directory

That’s just a small snippet, but usually, I have most projects set up with a very small alias. But even if I don’t have one set up for each project, I’ve got one that puts me at the root of my developer folder anyway.

As for applications, I’ve got a few that I use a lot:

  • xc: Opens a xcodeproj in the current directory
  • xcw: Opens a xcworkspace in the current directory
  • vs: Opens the current directory in Visual Studio Code
  • fork: Opens the current directory in Fork - A Git GUI, for when I want to dig into any conflicts.

Git

Being a developer, I use Git quite a lot. And that is where oh my zsh comes in handy, as it comes with a huge number of aliases for common Git commands. Here’s a great cheatsheet.

Here are the ones I use the most, and also what the full command is:

  • gco: git checkout - checkout branch
  • gaa: git add --all - adds all changes in the current directory
  • gc -m "": git commit -v -m "" - commits the current changes with a message
  • gp: git push - pushes commits to the configured remote repo
  • gf: git fetch- fetches branches and tags from the configured remote repo

I’m aware that those are pretty minor commands, but they’re so much easier when they’re just one two or three letters.

Also, oh my zsh does come with an alias for committing changes with a message, but it’s gcmsg and that’s longer than just using gc with the -m option.

The most used Git command I use though has to be a little ZSH function I made myself:

function gacp {
    gaa; gc -m $1; gp
}

It stands for “git add commit push”, and as you can probably tell, it adds and commits the following changes, with the supplied message, and pushes it to the remote repository.

Most of the time I’m doing stuff like this:

gacp "JIRA-123 fix tests"

Woops!

FTP

I don’t use these a lot, but I do have a few aliases to update various websites. They basically use the scp command (secure copy) to transfer files from a local directory to a remote server. Guide.

This isn’t exactly what I have, but they all follow this rough syntax:

scp -r /Users/chris/website user@123.123.123.213:../var/www/

This will recursively upload the contents of a local directory to a remote server. I use this whenever I update changes to my blog theme.

HTTP Requests

Whether I’m working on a mobile app or REST API at work, I’m usually testing various requests throughout the day. And while I sometimes use a tool like Postman, especially when I’m building a collection for QA testers, I do find it a bit cumbersome sometimes. So that means I end up resorting back to the terminal.

I’ve seen a tool called httpie which does seem to be quite good, but I’ve found curl to be good enough for my uses.

Tip: If you’re stuck with the syntax and don’t have time to wade through documentation, I’d recommend using a tool like Postman to build the request, and you can then export the curl request.

Most of the time I’m just performing GET requests, so the syntax is simply:

curl https://dev.chrishannah.me/feed.json

If you need just the headers of the response there’s the -I option, and if I want both the headers and body it’s a lowercase -i.

Environment Variables

Usually, I’m using the command line because I want to test quite quickly, and with slight tweaks, so I find making the command as short as possible helps with this.

The first one for me is to use environment variables. So for example I’ll use one for the base URL of the API, and usually a few for any variables that need to be in the path, especially if these are user account numbers, as it makes it a lot easier to quickly test different scenarios.

This means that a request like this:

curl https://company.com/api/account/2a3e4832-14e6-430d-8c34-748f4626e864/transactions

Can be made a lot shorter by using two environment variables:

export base=https://company.com/api
export account=2a3e4832-14e6-430d-8c34-748f4626e864/transactions

Which means it can look like this:

curl $base/account/$account/transactions

The biggest benefit I find is that allows you to edit the command much easier.

Using Files

Another tip I have for curl is that if you have a bunch of headers that you need to use, then it helps to have these stored in a file.

You can do this by using the -H command followed by @ and then the filename. For example, this command will read the headers from a file named headers.txt:

curl https://website.com -H @headers.txt

The header file needs to be in this format:

Key: Value

So something like this would work:

Content-Type: application/json
Authorization: Bearer [token]

This is especially handy for me as most of our APIs at work require various authorisation tokens that can be quite large.

You can also use other options to use files for storing the body of the request, but I’ve not had much experience of that, so I’ll have to defer to google.

JSON

This goes hand-in-hand with making HTTP requests, in that the responses are usually JSON. For that I use the JSON processor, jq.

Most of the time, I’m just using it to “beautify” data from a curl request, so I pass through the response to jq by piping the output from curl to jq like so:

curl https://dev.chrishannah.me/feed.json | jq

What that does is take the response from the curl request and output a pretty printed version of it.

But you can also use jq to parse the JSON response and pick out certain fields.

So for example, a request to my blogs JSON feed at https://dev.chrishannah.me/feed.json will return a fair bit of JSON data. Something like this:

{
  "version": "https://jsonfeed.org/version/1",
  "title": "Chris Hannah's Dev Blog",
  "home_page_url": "https://dev.chrishannah.me/",
  "feed_url": "https://dev.chrishannah.me/feed.json",
  "description": "A devlog by Chris Hannah",
  "author": {
    "name": "Chris Hannah",
    "url": "https://chrishannah.me"
  },
  "items": [
    { ... }
  ]
}

But say I only wanted to read the author object, I’d just need to use this command:

curl https://dev.chrishannah.me/feed.json | jq '.author'

Which will return just this:

{
  "name": "Chris Hannah",
  "url": "https://chrishannah.me"
}

There’s a lot more it can do as well, and I’d recommend checking out these examples.


I’m sure there are tons of other resources that go into far more detail on what you can do with the command line. But I thought I’d share a few things that I use it for, just in case it might prompt others to find some ways to save themselves time!


What I’ve Been Up to Over the Past Few Weeks #

It’s been a while since I actually wrote something, and that’s mainly because of my university work that’s been piling up (I finish this June!), and also because I’ve been developing a few mini projects with Swift. The latter is what I’m going to be writing about today.

Basically, over the past few weeks I’ve been getting back into using the command line more. Why is a hard question, but mainly because I’m a nerd, and it’s pretty fun!

It started when I kept seeing a trend of more of the people I follow on Twitter, either retweet or post GIFs of command line apps. It also led me to Hyper, which is a terminal application, and it’s actually built using JavaScript, HTML, and CSS. You can also customise it a ton, especially with the massive amount of themes available.

I personally, have Hyper set up with the hyper-ayu theme, and my favourite monospaced font, SF Mono.

This is getting a bit too meta, so I’ll bring it back on topic.

So I’ve actually developed four command line applications in the past two weeks, and they’ve all been build using Xcode/Swift[1]. The apps themselves are unix executable files, that can just be double-clicked and ran, but on each project I include more helpful installation/usage information.

cwiki

(Not to be mistaken with my macOS app, Qwiki)

This is the first one I made, and it was probably the easiest of them all. That’s because the majority of the code I could just reuse from my already released app, Qwiki! This app, cwiki , is just a super minimal version of that app.

You just type cwiki followed by a search query, and it will print out the most relevant matches. It does however, only print out a basic description of the articles.

Check out cwiki on GitHub.

So after the first project, I was a bit more intrigued, I decided to make a more interactive app. slink is purely a URL shortener that uses the Goo.gl API, but this lets you shorten, and also expand (Goo.gl) shortened links.

The slightly more complex functionality than before, led me to work out how options are managed in command line apps. So if you want to shorten or expand a link, just use either -s, --shorten, -e, or --expand. I also made a mini usage guide, that you can print out using -h or --help 🤓.

Check out slink on GitHub.

hacker

The third project was a bit similar to the first two, in that it made use of a few different options to return different data, but it also presented it like cwiki.

It’s a basic interface for Hacker News, and by making use of the various options, you can retrieve the new, top, and best lists.

Check out hacker on GitHub.

TitleCase

Okay this one is really simple, it makes use of Brett Terpstra’s TitleCase API, which formats a given string of text to the AP Title Case style. I actually find these types of tools perfect when writing a blog post, as usually the title is formatted incorrectly.

The API was probably the easiest one I’ve ever used. But then again, there was only one parameter, no options, and one return type.

Check out TitleCase on GitHub.


Now I guess everyone knows what I’ve been up to, so I can get back to slaving away over university work, and making some random projects!

P.S. I actually have some other really great news that I’m going to share here soon, but I’m just waiting on it being finalised a bit more.


  1. My favourite programming language 😍. ↩︎