« RFID chips for Ellie and Hop Hop | Main | Trust Bounty »

April 25, 2005

Shell tricks and tips

Recently, I started developing exclusively on a remote Linux box. Thanks to Andy I've picked up quite a few shell tricks that have been exceedingly useful. I use zsh at work, but I'm pretty sure they all work on bash as well. Recently, when talking with some friends who are Linux veterans, I was surprised to learn that some of these commands were new to them. Of course, I also learned a new trick or two from them. Here's my list, am I missing any gems?

  1. Tab completion of directory/file names/environment variables - I'm embarrased to say that when I first started to teach myself Linux, it took me about 6 months to learn about tab completion. It was even longer until I realized that tab also completed environment variables. I mention it here because I'm sure I'm not the only one. ;-)
  2. CTRL-W delete word
  3. CTRL-E go to end of line
  4. CRTL-A go to beginning of line
  5. CTRL-R recent command completion - This is one command that wasn't known by too many people. It allows you to search quickly through your command history for previously typed commands. It helps to have a large command history: export HISTSIZE=1000.
  6. CTRL-U Discard line, this works well when you think you've mistyped a password and need to start over.
  7. CTRL-K cut line from cursor
  8. CTRL-Y paste line in buffer
  9. !! (the last command) - I mostly use this when I forget to sudo a command For example:
    rm foo
    sudo !!
  10. !$ (the last argument of the last command)
    Let's say I'm tailing a log, but I want to see more than just the last few lines.
    tail -f /var/log/cron (quit tail)
    less !$

    or you just edited your .bashrc with vim and now want to source it
    vim ~/.bashrc (quit vim)
    source !$
  11. search for any files/directories recursively starting with the current directory and look for any occurance of foo in the name.
    find . -type f | grep foo
    OR
    find . -name "*foo*"
  12. xargs - Takes the output of the preceding command and appends them to the end of the following command. I think it's actually a bit more complicated than this, but the examples that follow do work.
    Here's a use of xargs with find to search within any files/directories recursively starting with the current directory and look for any occurance of foo *within* any of the files
    find . -type f | xargs grep foo
  13. Have you ever accidentally un-zipped a file into the wrong directory and wanted an easy way to undo. You can use xargs to remove the files by first listing the files in the archive, passing that list to xargs with rm (you have to be careful with this one):
    tar xzf foo.tgz
    tar tzf foo.tgz | xargs rm -rf
  14. How about wanting to get all files with foo in them, but you don't want the vim turd files. Note the escaped ~, this is done so that the shell doesn't first convert the ~ to /home/foo. Just remember that the shell will first parse the line, and *then* pass it to the binary. This type of issue still trips me up from time to time.
    find . -type f | xargs grep foo | grep -v \~
  15. pushd/popd - pushd will store the current directory in a stack. When you're ready to return to that directory at some later time, just type popd.
  16. cd - will take you to the previous directory (Thanks to Brain Pikkaart for this one).
  17. screen - (Thanks to Joel for first introducing me to screen ages ago.) I've got a linux development server at work that I connect to from my laptop. From man: "Screen is a full-screen window manager that multiplexes a physical terminal between several processes (typically interactive shells)." I've got screen running with 7 shells that I can toggle between. Following Andy's lead, I've setup screen with the following:

    0 - live server
    1 - backup server
    2 - vim
    3 - shell work on shared libraries
    4 - shell work on services
    5 - logs
    6 - mysql
    7 - scratch

    When I'm ready to leave, I just detach my screen session and go home. When I'm ready to start working again, I ssh into my development box, and (screen -r) will reattach my session and I'm back exactly where I left off.


Posted by mark at April 25, 2005 3:32 PM Subscribe (FeedBurner)

Comments

Nice list! I learned a new one from you; the double-bang in #9.

Posted by: alan at April 25, 2005 6:50 PM

Coupla good ones in there! I personally learned !$, which is good times. Some notes:

11. You can do SO much with find. find . -type f -name "*foo*" finds just files named "*foo*". find . -perm +4000 finds all entries that have the suid bit set (regardless of any other permissions set). And so on - really quite happy stuff.

12. xargs uses your shell's limits to append the arguments received on stdin to the argument given to xargs. Shell limits are why you cannot do rm -f * in a directory with 200K files - you must do ls | xargs rm -f instead.

Also, another cool feature of the find | xargs combo is the -print0 option to find and -0 option to xargs. This will separate the arguments (printed by find and used by xargs) with NULL bytes, rather than whitespace. This allows you to operate on files with spaces or other non-printable characters in their titles.

17. I've never been able to get excited about screen. Whoops, hang on - there's someone at the door. Oh look, it's the geek club looking to revoke my membership. :-P

Posted by: pcg at April 26, 2005 12:17 AM

Damn you and your lack of HTML tags to do monospaced fonts in comments.

Posted by: pcg at April 26, 2005 12:17 AM

Excellent stuff - thanks. Who knows what's going on? I've got HTML turned on for comments ...

Posted by: Mark Veerman at April 26, 2005 6:40 AM

Alright - tt, code, and pre tags are now allowed in blog comments. I didn't realize there was a sanitize spec configuration. You're welcome. ;-)

Posted by: Mark Veerman at April 26, 2005 6:58 AM

It took me a few minutes to figure out that 2-8 where emacs commands. I wonder how the vi folks feel about learning emacs commands for use on the shell. I'm afraid I will find myself typing CTRL-X,CTRL-C to exit the shell and then get confused.

Posted by: Nathan at April 26, 2005 9:49 AM

i knew those were emacs commands from the moment i laid eyes on them. :) i got sucked into emacs when i started the cs program at suny here in albany, ny.

Posted by: palletjackracer at April 26, 2005 8:29 PM

That's the thing - I'm a vim guy, through and through... yet I "set -o emacs" in my bash shell. (And they're emacs *bindings*, not commands, as far as I'm concerned. ;-)

Posted by: pcg at April 28, 2005 1:08 AM

Yeah, I considered using vim bindings for about 30 seconds, but I decided that I'm already comfortable with emacs bindings, and I won't have Nathan's problem of trying to exit my shell with vim commands. ;-)

Posted by: Mark Veerman at April 28, 2005 10:20 AM

Post a comment




Remember Me?

(you may use HTML tags for style)