Huh? Or, A Grep Too Far

I don’t like Unix. I’ve learned Unix the same way that I learned the layout of the dark living room at night when I was a child, through sharp, sudden and painful lessons about how the World is and in absolute fear that I’ll fuck up Something so badly that somebody else will notice. Unix is not for me and I, I am not for it. But, there aren’t any other practical options besides Unix, so here I am reading man pages for a living.

strace is the lone bridge that transports me from living in a cargo cult fear of Unix, and operating systems more generally, across to a passive aggressive tolerance of the way computers work. Julia Evan’s passion for strace and all the things it lets her see about computers work was really amazing to see and I thank her for all her shared and public excitement. She definitely made operating systems more approachable and opened doors for folks. I still don’t really like Unix but at least now I have the tools to more accurately pinpoint my criticisms.

The main thing I don’t like about Unix is the command line tools. The interfaces to interact with the command line tools simply aren’t consistent. There’s no rule to learn that will help with remembering all the flags and options, no mnemonic to help you remember how to untar something. I can only remember so many things and I’ll be damned if the weird options for some program somebody wrote two decades ago takes priority in my memory over, well, literally anything else frankly. Moreover, the tools communicate via text only and have no regard for the structure of data coming out.

Using strace has drilled home this twined disdain for Unix I have. strace lists the system calls a program makes throughout the program’s execution. It takes a bewildering number of command line flags and outputs the representation of the syscalls to stdout as strings. As I’ve grown to depend on strace more in my day to day programming, the frustration of a half dozen flags to remember and stringly typed output has gnawed at me. huh is my attempt at allaying these frustrations.  I’m tired of grepping through the output of strace and having to craft the perfect string to learn what I want to know. huh runs a program using strace with all the Right Flags, parses the strace output and stuffs all of that newly structured information into Postgres. From there it drops into a psql repl and lets you mess around with the data. Here’s an example:

vagrant@vagrant:/vagrant$  ./huh ls  dev-resources  doc  huh  huh.sql    LICENSE  project.clj  resources  src  target  test  Vagrantfile
psql (9.5.3)
Type "help" for help.

huh=# select count(*) from huh_1466374554;
(1 row)
huh=# \x
Expanded display is on.
huh=# select * from huh_1466374554 limit 1;
-[ RECORD 1 ]-+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
pid           | 8622
time          | 2016-06-19 22:15:54.053177
instruction   | 00007f627c863cf7
command       | execve
args          | ["\/bin\/ls",["ls"],["XDG_SESSION_ID=4","SHELL=\/bin\/bash","TERM=xterm-256color","SSH_CLIENT= 54529 22","SSH_TTY=\/dev\/pts\/1","USER=vagrant","LS_COLORS=rs=0:di=01;34:ln=01;36...","PATH=\/home\/vagrant\/bin:\/usr\/loca...","MAIL=\/var\/mail\/vagrant","PWD=\/vagrant","LANG=en_US","HOME=\/home\/vagrant","SHLVL=2","LANGUAGE=en_US:","LOGNAME=vagrant","SSH_CONNECTION= 54529 10...","LESSOPEN=| \/usr\/bin\/lesspipe %s","XDG_RUNTIME_DIR=\/run\/user\/900","LESSCLOSE=\/usr\/bin\/lesspipe %s %...","_=\/usr\/bin\/strace"]]
return        | "0"
return_msg    |
total_runtime | 00:00:00.000071

huh=# select distinct pid from huh_1466374554;
-[ RECORD 1 ]
pid | 8622

huh=# select command, count(*) from huh_1466374554 group by 1;
     command     | count
 open            |     9
 exited          |     1
 write           |     1
 exit_group      |     1
 brk             |     3
 access          |     7
 mprotect        |    12
 rt_sigprocmask  |     1
 rt_sigaction    |     2
 arch_prctl      |     1
 set_tid_address |     1
 getrlimit       |     1
 mmap            |    19
 fstat           |    10
 read            |     7
 munmap          |     1
 set_robust_list |     1
 close           |    11
 ioctl           |     2
 getdents        |     2
 execve          |     1
 statfs          |     2
(22 rows)

It’s built on top of instaparse and clojure, mostly because the strace output can be pretty weird. No guarantee that it covers everything that comes out of strace or that it won’t fuck up your computer if you try to use it. I’ve been developing and using huh inside of a VM via vagrant.

That’s all for now, still hating on Unix, working on ways to mitigate the bad parts.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s