Today I learned

I learn new bits every day. Here, I’ll try to share the things that I learned that might be useful to others, too.

December 3rd

Moving the terminal cursor

When you write stuff to the terminal, characters are printed from left to right, and wrap around the right hand side of the terminal onto the next line if necessary. That’s how a terminal typically works, but a terminal is also a matrix—each character position in the terminal has X and Y coordinates—and there are ways to write text at arbitrary positions, and thus use the terminal as a drawing board.

The way to do this is by writing the control sequence introducer (CSI) \e[, followed by instructions that describe what precisely you want to do.

A CSI followed by the character B will move the cursor down a single line. For example, the following Ruby code

puts "hello\e[Bworld"

will print


A moves the cursor up, B moves it down, C moves it right, and D moves it left.

You can prefix it with a number to make it move the given distance:

puts "hello\e[10Cworld"
hello          world

G moves it to the beginning or the line, or to the given column if you give it a number:

puts "2 + 3 = 7\e[G4"
4 + 3 = 7

K erases all characters after the cursor. For example:

(1..3).cycle.each do |num|
  $stdout << '.' * num << "\e[K" << "\e[G"
  sleep 0.2

will forever print dots:

November 22nd

tee and sudo

tee is a command that passes everything from standard input into standard output, but also writes everything read from standard input to a file:

% echo hi | tee greeting.txt
% cat greeting.txt

tee becomes useful when you want to redirect as root. Imagine a read-only directory:

% sudo ls -l | grep restricted_files
drwxr-xr-x  2 root     staff     68 Nov 21 21:39 restricted_files/

Redirecting with sudo doesn’t work, because sudo does not affect redirection:

% sudo echo hi > restricted_files/greeting.txt
An error occurred while redirecting file 'restricted_files/greeting.txt'
open: Permission denied

Piping the command through tee run as root, however, does work:

% echo hi | sudo tee restricted_files/greeting.txt
% cat restricted_files/greeting.txt

As an added benefit, the original command is no longer being run as root.

November 21st


Ruby has Thread.list, which returns a list of all threads in the current process:

irb> Thread.list
=> [#<Thread:0x007f8caa07f448 run>]

irb> { sleep 1000 }
=> #<Thread:0x007f8ca988abc0@(irb):2 run>

irb> Thread.list
=> [
  #<Thread:0x007f8caa07f448 run>,
  #<Thread:0x007f8ca988abc0@(irb):2 sleep>]