Today I Learned

17 posts about #command-line

Move cursor word by word on iTerm


Cursor navigation can be slow on iTerm


Enable word by word cursor movement

Preferences > Profiles > Keys > Select + to add new key mapping

To move left:

Keyboard Shortcut: ⌥ ←
Action: Send Escape Sequence
Esc+ b

To move right

Keyboard Shortcut: ⌥ →
Action: Send Escape Sequence
Esc+ f


Searching Through Gems

Sometimes you need to peak at the source of a class or method of a gem from your Gemfile. Since gems are managed by bundler, it has a command-line option that can help.

bundle show --paths will list the paths of all the gems from your Gemfile. You can grep through these directories to search.

I'm currently using ripgrep for searching at the command line, so can pass the paths there.

Here’s it all together in a simple Bash function:

function bundle-search() {
    rg $1 `bundle show --paths`

Changing Your iterm2 Profile Programmatically

Change your iterm2 profile to Production with this command:

echo -e\033]50;SetProfile=Production\a

Create a function to make it easier to switch profiles:

function iterm_profile {
  if [[ -z $1 ]]; then

  echo -e "\033]50;SetProfile=$profile\a"

I use this feature to let me know I am working on the Rails migration.


Diff CSVs With Ease

We're all familiar with diff tools like RubyMine, vimdiff, or the good old diff command. These work well for source code but are not optimal for CSVs files, which may have many columns and rows.

I found myself wanting to write CSV-specific diff tool, but I fought that Not Invented Here impulse and Googled first. I found a good Python library called csvdiff.

Imagine we have the following CSV file:

1,Alan Turing
2,John McCarthy
3,Edger Djikstra

We want to compare it to another file:

1,Alan Turing
3,Edsger Dijkstra
4,John Von Neumann

We've removed, edited, and added a row. The summary option confirms our changes:

$ csvdiff --style=summary id one.csv two.csv
1 rows removed (33.3%)
1 rows added (33.3%)
1 rows changed (33.3%)

The detailed view gives us all the gory details:

$ csvdiff --style=pretty id one.csv two.csv
  "_index": [
  "added": [
      "id": "4",
      "name": "Jon Von Neumann"
  "changed": [
      "fields": {
        "name": {
          "from": "Edger Djikstra",
          "to": "Edsger Dijkstra"
      "key": [
  "removed": [
      "id": "2",
      "name": "John McCarthy"

pgcli — a great alternative to psql

Ever wished for a feature-rich, intuitive command-line postgresql client? Look no further! Presenting, pgcli — a result of pouring creativity into features rather than the name of the tool.


  • Smart autocompletion for almost anything. Even column names in the select query are properly autocompleted from the table you are selecting from;
  • Multi-line query editing support;
  • SQL Syntax highlighting;
  • CLI parameters compatible with psql params. No need to relearn anything;
  • Vi mode, allowing to edit multi-line queries using some of the vi bindings. There are also Emacs bindings too;
  • Installation as easy as pip install pgcli (and if that fails, fix is as easy as xcode-select --install (usually));

Grab your copy today!

OS X Command Line

I love being able to use Alfred as a kind of GUI command line...

..and I also like using the command line to get things done. I just discovered all sorts of new things that I can do from the command line from this GitHub repo.

For example, to show Wi-Fi Connection History:

defaults read \
  /Library/Preferences/SystemConfiguration/ | \
  grep LastConnected -A 7

Encrypt data using psql + keybase

To export any query to a CSV and send it to stdout one can use:

psql -c "\copy (select version()) to stdout csv header"

So you can just replace select version() with any query in the above command and the results will be dumped in your terminal screen. If you have any sensitive data that is not already encrypted you could pipe this results directly to keybase as in:

psql -c "\copy (select version()) to stdout csv header" | keybase encrypt diogob

Where diogob is the recipient of your message (or your own username in case you want to store this file for future use).

Run last command in BASh/ZSH (they're different)

To run the last executed command in BASH, execute the following:


In ZSH, things are a little different. Using !! will only expand the command into the shell prompt. You would have to press enter again to execute it. Rather, if you want to immediately execute the last command similar to BASH, use this:


If you prefer for ZSH behaviour to match that of BASH, then add setopt no_hist_verify to your .zshrc file.

Am I executing the correct executable?

Q: When I run a command (let's say rails), which executable is it executing?


> which rails

Q: Ah, I see which one it's running. And it's not the right one! Where are all the potential executables, given the current PATH?


> where rails

Now I know whether it's a PATH ordering issue, or whether it's not included PATH at all.

Non-Invasive Monitoring of Socket Traffic


I would like to diagnose failures to communicate with an external service over a network socket, without making modifications to the code or otherwise disturbing a production-like environment.


One writes to or reads from a socket by making a request to the kernel (a.k.a syscall). This requires the file descriptor (numerical identifier) of the socket and the message to be sent over the socket, or a buffer that will contain the next message read from the socket.

Using strace (or dtruss on MacOS), one can inspect the stream of syscalls issued to the kernel and the arguments for each syscall. First, find the ID of the process that will be communicating over the socket:

ryan@staging ~ $ ps ax | grep unicorn
99999 ?        Sl     0:00 unicorn worker[0]

Then attach to the process with strace:

ryan@staging ~ $ strace -p 99999
Process 99999 attached
[pid 99999] write(11, "Hello", 6) = 6
[pid 99999] read(11, 0xBAAAAAAD, 64) = -1 EAGAIN (Resource temporarily unavailable)

Here, a Hello message was sent with a write syscall over socket with file descriptor 11, though the read syscall failed as the socket was temporarily blocked.

Performance Metrics for Scripts Using Command Line

To quickly collect performance metrics for a script via command line:

  1. Start running the script. Make note of the process name that the script is running as (e.g. ruby)
  2. Create a script called with this content: ps aux | grep $1 | head -1 | awk '{print "CPU="$3 ", MEM="$4 ", RSS="$6}'
  3. Make the profiler executable: chmod +x
  4. Execute the profiler in a watch session every minute: watch -n 60 --no-title "./ SCRIPT_IDENTIFIER | tee -a logfile". Where the script identifier is any text that we can use to grep for the process in the ps aux output.
  5. After your script is done running or you have enough data points, observe the output in logfile.

NOTE: RSS is resident set size


Fish-like fast/unobtrusive autosuggestions for zsh.

I followed the installation instructions for Oh My Zsh and works for me.

My command line life is so much sweeter.

How to see invisible text in iTerm2

Yesterday, I tried to run 'npm test' for a new project and the text was invisible (i.e. the same color as the background color of my chosen color scheme for iTerm2). You can find a long discussion about this problem here:

Buried in this discussion was the solution: iTerm2 -> Preferences -> Profiles -> Colors -> Minimum contrast -> Move slider about a third of the way

NPM: List available custom scripts in the CLI

If you are working in the CLI on a project that uses NPM and you want to know what what custom scripts are available to you, without need to open and scroll through package.json, just simply execute:

npm run

and all your custom scripts will be outputed to the screen.

Enable Mac Keyboard Number Pad in iTerm

If you Mac keyboard's number pad is not working in iTerm, then follow the steps outlined here:

Looks like the answer is to go into Preferences->Profiles->Keys
and load preset of: xterm with numeric keypad.

You will lose any default key mappings that you already set in your iTerm profile already, so you may want to do this in a brand new profile so you can bring over your old mappings to the new profile and not outright lose them like I just did.

Share a TTY under Linux


  1. Set the screen binary (/usr/bin/screen) setuid root. By default, screen is installed with the setuid bit turned off, as this is a potential security hole.

  2. The teacher starts screen in a local xterm, for example via screen -S SessionName. The -S switch gives the session a name, which makes multiple screen sessions easier to manage.

  3. The student uses SSH to connect to the teacher's computer.

  4. The teacher then has to allow multiuser access in the screen session via the command Ctrl-a :multiuser on (all screen commands start with the screen escape sequence, Ctrl-a).

  5. Next the teacher grants permission to the student user to access the screen session with Ctrl-a :acladd student where student is the student login ID.

The student can now connect to the teacher's screen session. The syntax to connect to another user's screen session is screen -x username/session.

Running past commands from history

There are many ways to search/recall previous commands from the command line but I find the combination of history and !<history_id> to be quite useful, especially when you don't remember the command you ran. For example:

Show me my previous commands:

> history
  513  git stash pop
  514  rspec spec/some_spec.rb
  517  git diff
  518  git add -p

Re-run the spec command in 514

> !514