Writing Beautiful Command Line Programs John Leach @johnleach June - - PowerPoint PPT Presentation

writing beautiful command line programs
SMART_READER_LITE
LIVE PREVIEW

Writing Beautiful Command Line Programs John Leach @johnleach June - - PowerPoint PPT Presentation

Writing Beautiful Command Line Programs John Leach @johnleach June 2012 John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 1 / 44 Intro Text only interfaces Text user interfaces (TUI) Command line interfaces (CLI)


slide-1
SLIDE 1

Writing Beautiful Command Line Programs

John Leach

@johnleach

June 2012

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 1 / 44

slide-2
SLIDE 2

Intro

Text only interfaces

Text user interfaces (TUI) Command line interfaces (CLI)

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 2 / 44

slide-3
SLIDE 3

Intro: Text User Interfaces

Lotus 1-2-3

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 3 / 44

slide-4
SLIDE 4

Intro: Text User Interfaces

Microsoft Word 5.5

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 4 / 44

slide-5
SLIDE 5

Intro: Text User Interfaces

make menuconfig

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 5 / 44

slide-6
SLIDE 6

Intro: Command Line Interfaces

shell

$ uptime 12:59:52 up 16 days , 1:53 , 1 user , load average : 0.87 , 0.66 , 0.70 $ df −h F i l e s y s t e m S i z e Used A v a i l Use% Mounted on / dev / sda2 75G 64G 7.1G 90% / $ ping −c1 8 . 8 . 8 . 8 PING 8 . 8 . 8 . 8 ( 8 . 8 . 8 . 8 ) 56(84) bytes

  • f

data . 64 bytes from 8 . 8 . 8 . 8 : icmp_req=1 t t l =49 time=163 ms − − − 8 . 8 . 8 . 8 ping s t a t i s t i c s − − − 1 packets transmitted , 1 r e c e i v e d , 0% packet l o s s , time 0ms r t t min/avg/max/mdev = 163.747/163.747/163.747/0.000 ms

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 6 / 44

slide-7
SLIDE 7

Intro: Command Line Interfaces

Brightbox Cloud API

$ brightbox-servers list id status type zone created_on image_id cloud_ip_ids name

  • srv-f7dye

active nano gb1-b 2010-12-03 img-9vxqi cip-8ks0v tor1 srv-v4rjq active mini gb1-b 2011-01-22 img-9vxqi cip-ye4ue ququ-web srv-uicfm active small gb1-a 2011-05-08 img-2ab98 cip-46qrn newsniffer srv-veehc active small gb1-a 2011-06-05 img-4gqhs cip-tqg43 web1 srv-crpty active nano gb1-a 2011-08-06 img-4gqhs cip-m1e98 humanweb srv-98rr6 active nano gb1-a 2011-11-25 img-3fsuy cip-8u19j claw srv-8hecw active mini gb1-a 2012-02-23 img-ytx00 cip-zd2me mycogen srv-aae27 inactive mini gb1-a 2012-04-11 img-715uq debiantest srv-qulcn active nano gb1-b 2012-05-09 img-9h5cv apacheds test srv-aa5jn active nano gb1-a 2012-05-09 img-9h5cv amq

  • John Leach (@johnleach)

Writing Beautiful Command Line Programs June 2012 7 / 44

slide-8
SLIDE 8

Input and Output

Input and Output

stdin: text typed at a keyboard stdout: text emitted by the program stderr: more text emitted by the program

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 8 / 44

slide-9
SLIDE 9

Input and Output

stdin, stdout, stderr in Ruby

puts STDIN . i n s p e c t #<IO:0x7f353af81a08> puts STDOUT. i n s p e c t #<IO:0x7f0b08eb09f0> puts STDERR. i n s p e c t #<IO:0x7ff7e60df9b8>

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 9 / 44

slide-10
SLIDE 10

Input and Output

stdin and stdout in Ruby

echo " h e l l o " | ruby −e ’ puts STDIN . read ’ hello

  • STDOUT. puts

" world " world

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 10 / 44

slide-11
SLIDE 11

The ls command

ls to your terminal

$ l s . cmd i n i t . rb ruby−token . rb completion . rb input −method . rb s l e x . rb context . rb l c v e r s i o n . rb ext l o c a l e . rb workspace . rb extend−command. rb n o t i f i e r . rb ws−for−case −2. rb frame . rb

  • utput−method . rb

xmp . rb help . rb ruby−l e x . rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 11 / 44

slide-12
SLIDE 12

The ls command

ls to another program

$ l s . | grep ruby ruby−l e x . rb ruby−token . rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 12 / 44

slide-13
SLIDE 13

The ls command

ls errors go where?

$ l s . _why | grep ruby l s : cannot access _why : No such f i l e

  • r

d i r e c t o r y ruby−l e x . rb ruby−token . rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 13 / 44

slide-14
SLIDE 14

The ls command

ls errors go to stderr

$ l s . _why 2> e r r o r . log | grep ruby ruby−l e x . rb ruby−token . rb $ cat e r r o r . log l s : cannot access _why : No such f i l e

  • r

d i r e c t o r y

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 14 / 44

slide-15
SLIDE 15

The ls command

ls for humans

$ l s cmd i n i t . rb ruby−token . rb completion . rb input −method . rb s l e x . rb context . rb l c v e r s i o n . rb ext l o c a l e . rb workspace . rb extend−command. rb n o t i f i e r . rb ws−for−case −2. rb frame . rb

  • utput−method . rb

xmp . rb help . rb ruby−l e x . rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 15 / 44

slide-16
SLIDE 16

The ls command

ls for programs

$ l s . | grep ruby ruby−l e x . rb ruby−token . rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 16 / 44

slide-17
SLIDE 17

The ls command

ls knows when you’re not human

$ ls | cat cmd completion.rb context.rb ext extend-command.rb frame.rb help.rb init.rb input-method.rb lc locale.rb notifier.rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 17 / 44

slide-18
SLIDE 18

The ls command

ls in for loops

$ for f in ‘ ls ‘ ; do > echo Doing something with $f > done Doing something with cmd Doing something with completion . rb Doing something with context . rb Doing something with ext Doing something with extend−command. rb Doing something with frame . rb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 18 / 44

slide-19
SLIDE 19

The ls command

Detecting humans

$ ruby −e ’ puts STDIN . i s a t t y . inspect ’ true $ echo h e l l o | ruby −e ’ puts STDIN . i s a t t y . inspect ’ f a l s e

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 19 / 44

slide-20
SLIDE 20

The terminal

Terminal width

80 characters detect and adapt i r b ( main ):001:0 > ENV[ ’COLUMNS’ ] = > " 80 " i r b ( main ):002:0 > ENV[ ’ LINES ’ ] = > " 24 " $ s t t y s i z e 24 80

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 20 / 44

slide-21
SLIDE 21

The terminal

Use of colour

ls grep

  • nly if a tty

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 21 / 44

slide-22
SLIDE 22

Tables

Drawing nice tables with Hirb

table [Time.now, Time.now + 3600], :fields => [:to_s, :to_i] +--------------------------------+------------+ | to_s | to_i | +--------------------------------+------------+ | Wed Jun 27 10:26:57 +0100 2012 | 1340789217 | | Wed Jun 27 11:26:57 +0100 2012 | 1340792817 | +--------------------------------+------------+ 2 rows in set

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 22 / 44

slide-23
SLIDE 23

Tables

Vertical tables

table [Time.now, Time.now + 3600], :fields => [:to_s, :to_i], :vertical => true ****** 1. row ****** to_s: Wed Jun 27 11:04:21 +0100 2012 to_i: 1340791461 ****** 2. row ****** to_s: Wed Jun 27 12:04:21 +0100 2012 to_i: 1340795061 2 rows in set

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 23 / 44

slide-24
SLIDE 24

Tables

Hirb::Table vs. Brightbox::SimpleTable

Brightbox::SimpleTable to_s to_i

  • Wed Jun 27 11:17:04 +0100 2012

1340792224 Wed Jun 27 12:17:04 +0100 2012 1340795824

  • Hirb::Table

+--------------------------------+------------+ | to_s | to_i | +--------------------------------+------------+ | Wed Jun 27 10:26:57 +0100 2012 | 1340789217 | | Wed Jun 27 11:26:57 +0100 2012 | 1340792817 | +--------------------------------+------------+ 2 rows in set

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 24 / 44

slide-25
SLIDE 25

Whitespace

Whitespace and awk

echo " h e l l o ␣␣ world " | awk ’{ p r i n t $2 } ’ world echo " h e l l o ␣ | ␣ world " | awk ’{ p r i n t $2 } ’ | echo " h e l l o ␣ | ␣ world " | awk −F ’ | ’ ’{ p r i n t $2 } ’ world

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 25 / 44

slide-26
SLIDE 26

Whitespace

Awk and xargs in action

$ brightbox-servers list | grep inactive | > awk ’{print $1}’ | xargs brightbox-servers show id: srv-aae27 status: inactive name: debiantest created_at: 2012-04-11T20:27Z deleted_at: zone: gb1-a type: typ-iqisj type_name: Brightbox Mini Instance type_handle: mini ram: 1024 cores: 4 disk: 40960 private_ips: 10.240.160.222 cloud_ips: ipv6_address: 2a02:1348:14c:2837:24:19ff:fef0:a0de cloud_ip_ids: hostname: srv-aae27 public_hostname: ipv6_hostname: ipv6.srv-aae27.gb1.brightbox.com snapshots: server_groups: grp-98v4n

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 26 / 44

slide-27
SLIDE 27

Whitespace

Whitespace and the mouse

If a mouse clicks and your program isn’t listening for it, does it do anything?

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 27 / 44

slide-28
SLIDE 28

Configuration

command line arguments

ARGV ruby −e ’ puts ARGV. inspect ’ −− −a h e l l o −b world ["-a", "hello", "-b", "world"]

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 28 / 44

slide-29
SLIDE 29

Configuration

command line arguments

Long form and short form Commonly used options (-h, -v)

  • f - for stdin

OptionParser GLI

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 29 / 44

slide-30
SLIDE 30

Configuration

environment variables

No parsing needed! Secure! MSG =" h e l l o ␣ world " ruby −e ’ puts ENV[ "MSG" ] ’ hello world

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 30 / 44

slide-31
SLIDE 31

Configuration files

Config file specification

plain text line orientated support comments

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 31 / 44

slide-32
SLIDE 32

Configuration files

config file formats

noxml = separated key values ini if you need sections yaml isn’t too bad

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 32 / 44

slide-33
SLIDE 33

Configuration files

XDG Base Directory Specification

data goes in ˜/.local/share/yourapp config goes in ˜/.config/yourapp non-essential data goes in ˜/.cache/yourapp

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 33 / 44

slide-34
SLIDE 34

Configuration files

auto-setup

create the directories you need automatically if you need a config, provide a tool to create one

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 34 / 44

slide-35
SLIDE 35

Auto-completion

Auto-completion

Typing is error prone and noisy Remembering long options is hard hyphens and whitespace

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 35 / 44

slide-36
SLIDE 36

Auto-completion

brightbox commands

$ brightbox brightbox brightbox −images brightbox −accounts brightbox −l b s brightbox −c l o u d i p s brightbox −s e r v e r s brightbox −c o n f i g brightbox −types brightbox −f i r e w a l l −p o l i c i e s brightbox −u s e r s brightbox −f i r e w a l l −r u l e s brightbox −zones brightbox −groups $ brightbox −f i r e w a l l − brightbox −f i r e w a l l −p o l i c i e s brightbox −f i r e w a l l −r u l e s

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 36 / 44

slide-37
SLIDE 37

Auto-completion

brightbox-firewall-rules

$ brightbox −f i r e w a l l −r u l e s c r e a t e destroy help l i s t show $ brightbox −f i r e w a l l −r u l e s c r e a t e −− −−d e s t i n a t i o n −−icmptype −−source −−dport −−p r o t o c o l −−s po rt $ brightbox −f i r e w a l l −r u l e s c r e a t e −−source=any fwp− fwp−fx45z fwp−ln6wh fwp−qhdkl fwp−uba8q fwp−gasvb fwp−l z 4 r o fwp−q l r l 5 fwp−w9fl8 fwp−gtock fwp−mcxy6 fwp−r g j t 5 fwp−x572u

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 37 / 44

slide-38
SLIDE 38

Documentation

Documentation

basic inline –help man pages a page for each command info pages

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 38 / 44

slide-39
SLIDE 39

Documentation

man page

GREP(1) NAME grep, egrep, fgrep, rgrep - print lines matching a pattern SYNOPSIS grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] DESCRIPTION grep searches the named input FILEs (or standard input named, or if a single hyphen-minus (-) is given as file containing a match to the given PATTERN. By default, matching lines. In addition, three variant programs egrep, fgrep available. egrep is the same as grep -E. fgrep

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 39 / 44

slide-40
SLIDE 40

Misc

Prompting the user

user isn’t always a human! –force

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 40 / 44

slide-41
SLIDE 41

Misc

Return Codes

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 41 / 44

slide-42
SLIDE 42

Misc

Packaging

deb/rpm gem gem2deb

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 42 / 44

slide-43
SLIDE 43

Summary

Summary

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 43 / 44

slide-44
SLIDE 44

Summary

Writing Beautiful Command Line Programs

@johnleach john@johnleach.co.uk http://johnleach.co.uk http://brightbox.com

John Leach (@johnleach) Writing Beautiful Command Line Programs June 2012 44 / 44