2009/Command-Line Kung Fu: White Belt

From Open Source Bridge Wiki
Revision as of 17:04, 13 April 2011 by Igal (Talk | contribs) (Reverting vandalism.)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Come and learn some useful command-line short cuts and shell idioms that will make you vastly more productive in a Linux or Unix shell. Time permitting, we’ll even play “stump the expert”, so bring your thorniest shell problems.

Speaker: Hal Pomeranz

Return to this session's details

Contributed notes

Why is this hard

For some reason the smarts is not being handed down, the old crowd that know this are not really sharing because they take it for granted, and the new breed that that don't know what to ask. Thus we now have this wonderful talk =)

First this is a CLI class not a shell scripting class

We're going to be doing this hands on, we'll drop off the slides here soon.

We're going to focus on bash so if you have your own fixations then your on your own.

This talk will be geared for generalities, ie we're going to try and avoid the GNU awesomeness but in an effort to make this as useful as

If you missed something


Slides are avail on the site.

Thanks Hal Poneranz.

YTok52 YATB says you r the best

run the last command that started with


ok thats kinda risky lets see what that command would be


yup thats it lets run it


what if I want to deal with the last bit of the last line: !$

 sudo co -l /etc/httpd/httpd.conf
 vi !$

what about the whole thing?

 sudo mkdir /home/kevin
 # look back for /home/kevin
 sudo cp .bashrc .profile !$
 # look back for all args from the prev cmd
 sudo chown kevin !*
 # look back for the args of the command two steps back (you don't want kevin)
 sudo chmod 755 !-2*

forgot sudo

 co -l /etc/ntp.conf
 #!! failed 
 sudo !!

what in cases of mistype

  sudu vi
 #!! FAIL

managing files and directories


find {list of places to look} {predicates that define what to look for} {actions to take for matches}

find by type

find regular files under dev

 find /dev -type d -print

find by name

 find / -name '.* *' -print 

by size

find large files

 find / -size +10000000c -print

by time

find every file changed in the last week

 find / -mtime -7 -print

you only have day granularity, or does it...

Create a file with the right time stamp

 touch -t 20080116000 timestamp 

then fine for stuff that is newer

 find / -newer timestamp -print

use find to figure out what the gui did

you can use the same method, create a tmp file with the current timestamp

 touch /tmp/timestamp
 sudo find /etc -newer /tmp/timestamp

find just files that have a specific string

use exec to bring grep to the party.

{} is the substitution for find to insert the file name that matched the test yes you will need to escape the semi to end the line as you could chain multiple commands in exec.

 find /usr/include -type f -exec grep -l PATH_MAX {} /;

KQiQY0 Cool! That's a clever way of looking at it!

depth first

I want to delete only empty dirs, but want to capture all any parent that would match if I delete it's child:

 find . -depth -type d -d -exec rmdir {} \;

this works because rmdir will not remove non empty dirs. But it creates a bunch of warnings. if you have access to GNU find then you can use (does the same thing)

 find . -type d -empty -delete


quickie benchmarking

 time {YOUR CMD}



 for f in messages*.gz 
 echo ==== $f 
 zcat $f

 for f in messages*.gz; do; echo ==== $f; zcat $f 

And because this is UNIX you can pipe the output

 for f in messages*.gz; do echo ==== $f; zcat $f | grep .....

cmd sub

 for i in `seq 1 12 ` ; do mkdir $i; done

for (C style)

 for((i=1; $i  < 13; $i++)); do rmdir $i; done

using for to rename files with spaces to underscores

 for f in *; do mv -- "$f" ${f// /_}; done

This will clobber, ( ie 'foo bar' will over wright foo_bar if it already existed), so lets be more careful.

 for f in *; do n=${f// /_}; [ -f $n] || mv -- "$f" $n; done

In short, we save off the new filename, then check to see if a file already exists, if not then do the move.

while (infinite)

lets watch traffic on eth0 with an interval:

 while:; do netstat -in | grep eth0; sleep 5; done

GNU: look at watch

selecting subsets or want to cut out stuff


works really well for strongly delimited data (like passwd) example will list users

cut -f1,5 -d: /etc/passwd

f is the list of feilds that you want d is the delimiter


get a list of pids from ps

 ps -ef | awk '{print $2}'

you could use grep to limit just to ssh

 ps -ef | grep sshd | awk '{print $2}'

but awk already can do this

 ps -ef | awk ' /sshd/ {print $2}'

And awk can replace cut with -F

 awk -F: '{print $1 ":" $5}'


sort alphabeticaly

sort /etc/passwd  

or numericly

sort -n -k3 -t: /etc/passwd

n: numeric sort k: what colum to sort by (3) t: what to delimit on (:)

work out file create time, kinda

list a dir sort by inode

 ls -li | sort -n

you can kinda see groups of files that were created around the same time (if you are on a fs that hands out inodes in sequental order)


you can only remove duplicate from sorted data


 cut -f3 -d: /etc/passwd | sort | uniq


 cut -f3 -d: /etc/passwd | sort -u

but what if I want a count of the unique values?

 uniq -c

what if I want to see the duplicates (not the unique values)

 uniq -q

work out how many pids by user

 ps -ef | awk '{print $1}' | sort | uniq -c | sort -nr