Use bash like a hacker

(Prepared to be shared at my work: www.uniqueway.com smiley)

Through long trial and error, and with a healthy dose of help from the Linux from Scratch website, I've accumulated some good knowledge of Bash in my time with Linux and OS/X. Here are the highlights:

When I first got a Mac, I was frustrated by needing to interact with the point and click GUI all the time. My thesis advisor, Dan Lizotte, told me "But no, you need to think like a Mac user!". That's when he told me about two tricks. The first is pretty cool: open a terminal, type "cd ", and then drag and drop a folder from the Finder into your Terminal window. The path gets pasted in, and when you hit Enter you'll be sent to that folder!

The reverse is even more powerful:

open .                   # open the current directory in Finder
open song.mp3            # open the file with the normal program
                         # OSX would associate with that file
open -a VLC.app song.mp3 # open the file with a specific app!

Another great command that comes in useful all the time is sed. Here are some useful commands

echo "this is a test" | sed -e 's/test/sed test/' # outputs "this is a sed test"
sed -i'' -e 's/test/sed test/' file.txt           # replace words in a file in place
sed -i '' -e 's/test/sed test/' file.txt          # OS/X version of the above command

You'll need to use man regex to harness the full power of sed's replacements.

Grep is great, and really useful

grep "search string" file
cat file | grep "search string"
grep -v "inverted search" file
grep -r "line of code" somefolder # search a directory recursively
grep -r "line of code" *
grep -rl "line of code" *         # only output the filenames
grep -v '^#' file                 # -v inverts the match - this shows all lines NOT starting with #
grep -C 3 string file             # show the line plus the three lines before and after it
grep -A 2 -B 4 string file        # show the line plus 2 lines after and 4 lines before
grep -m 3 string file             # show a maximum of 3 matches

Often I have great success combining grep and sed to do incredible things when processing output. Another command that comes in handy when modifying files and streams is awk. The only command I ever really use with awk is this:

echo "one two three four five" | awk '{print $1 $5}'     # outputs "one five"
echo "one,two,three,four,five" | awk -f, '{print $1 $5}' # outputs "one five" by splitting on comma instead of space

Head and tail are also very useful:

head file     # show ten lines
tail file     # show last ten lines
tail -n+10    # show all but the last ten lines
head -n3 file # show first three lines
tail -n3 file # show last three lines
tail -f file  # show last ten lines of file, then stream output as it's added to the file (I call this "tailing a log file")

As is this crazy bash operator:

sudo apt-get install php5 php5-{apcu,gd,memcached,dev} # installs php5 php5-apcu php5-gd php5-memcached php5-dev
                                                       # by expanding the php5-{...} expression into 4 arguments

But I find my most productivity comes from the Bash-specific tricks. Bash is interesting; to get information on its built-in commands, you need to use "help command" instead of "man command", so a lot of them are kind of esoteric.

My favourite by far is history.

history            # output a numbered list of all your recent commands
!1000              # execute command 1000 from the history with the same arguments
!1000:p            # show command 1000, and let you hit the Up arrow key to modify and/or run the command
rspec cool_spec.rb
vim !$             # !$ is replaced by the last argument of the previous command
rspec !$           # so these two commands edit and then re-run rspec on cool_spec.rb
!!                 # re-run the previous command
sudo !!            # re-run the previous command via sudo
grep -rl string *  # get list of files containing the string
vim $(!!)          # edit the list of files you just found with grep
                   # $() runs a command and returns the output as arguments
!rs                # finds the most recent command in history starting with "rs" and runs it


You can also use "reverse-i-search" to search through your history a bit more efficiently than with !?. Just type Ctrl+R and then start typing the command you want. This is useful for instance if you want to re-run a command prefixed with sudo, because it's harder to match. ! only matches on the first word.

Add new comment