2009/Command-Line Kung Fu: White Belt

From Open Source Bridge Wiki
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

http://www.deer-run.com/~hal/

Slides are avail on the site.

Thanks Hal Poneranz.

YTok52 YATB says you r the best

run the last command that started with

 !/xrandr

ok thats kinda risky lets see what that command would be

 !/sudo:p 

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
 ^sudu^sudo

managing files and directories

find

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
 

time

quickie benchmarking

 time {YOUR CMD}

loops

for

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

 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

cut

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

awk

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}'

sorting

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)

uniq

you can only remove duplicate from sorted data

OLDSCHOOL

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

NEWSCHOOL

 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

Q/A