Showing posts with label CLI. Show all posts
Showing posts with label CLI. Show all posts

Monday, January 18, 2010

Shell shortcuts part deux.

In my last post, I demonstrated how you can use the !! and !$ features of your Bash & zsh history to get your work done more quickly.   I use the former all the time, but  the latter?  Well, not so much.  This is because I use something even better for interactive shell use.  It is M-.  That is Meta plus period.  All you Emacs zealots users will know what I mean by Meta.  :)  The Meta-key is Alt on your computer, or sometimes Esc.  Both work on my machine, but I prefer Alt over Esc, because it is less work.

Try doing M-. in your shell (Press and hold the Alt key, and then press the period key).  Like !$, M-. will give you the last part of the last command entered, but this time you can see it immediately.  Better still, you can cycle through all of your commands.  Just keep hitting M-. and the shell will display the last part of each command, in order, from newest to oldest.

Note:   If you use the ESC key for your 'Meta' key, then you need to release the ESC key each time.  Otherwise, if you hold it down and tap the . (period) key, it will return the end of the last command only once, and then start echoing the period after it.

As an example, say you had just finished a

grep fred /etc/passwd

You are ready to use the command line history feature:

vi M-.

Which would expand to (immediately):

vi /etc/passwd

Then, if it looks right, just press Enter.

Saturday, January 16, 2010

Shell shortcuts

In Bash and zsh, you can access the command history by using several shortcuts.  For example, by typing !![Enter], the previous command will be executed.  If you are not sure of what the previous command was, you could do !!:p[Enter] and the previous command will be displayed, but not executed.  Now, if you like what you see, you can do !![Enter], and the shell will execute that command.

Another ! shortcut is !$.   This will give you the end of the previous command.  So if my previous command was:

grep fred /etc/passwd

doing !$ would give me /etc/passwd.  This can be handy.  Say for example the user fred exists on the system, and grep returns his record from /etc/passwd.  If there is something I see in one of the fields that I wish to change, all I need to do (provided that grep was the last command I did) is:

vi !$

This will expand to

vi /etc/passwd

If you are not sure how !$ will expand for you (ie., you cannot remember for certain what your last command was exactly), you can use the :p option:

vi !$:p

Tuesday, January 12, 2010

Optimizing your shell scripts

A few days ago I came across a couple of posts, by Brock Noland, (blog site is dead now) about splitting strings natively with the shell.  You can find them here here (Internet archive) and here here. Basically, the writer demonstrated that using shell builtins and variables is much more desirable than using outside programs, such as cut and awk for the same purpose.  The reason for this is due to speed.  Every time you make a call to an outside program with the shell, you fork a new process, and that takes time.

I decided to tinker with this idea a bit more, to get a better impression of how much slower using cut and awk really is. I made each of the following functions iterate 100 times.  I am pretty sure some of you will be shocked by the speed difference between cut and awk, versus the shell native string splitting.

Monday, December 28, 2009

Using pushd, popd and dirs

Since I have a bit of time on my hands, I thought I might share a trick or two.  Well, not really 'tricks,' but good information to know. I will cover the shell builtins, pushd, popd, and dirs for bash and zsh. Additionally, I will demonstrate how to use some shell aliases, in order to make the use of these handy builtins even more convenient, and time saving.

Friday, December 18, 2009

ps headers and grep

GNU ps(1) has a plethora of options.  One of the more useful features of ps is the header label which is printed at the top of the ps output, such as in the following snippet:


Listing 1.1
char $ ps
  PID TTY       TIME CMD
15705 pts/1 00:00:00 bash
16345 pts/1 00:00:00 ps


As you can see, each column has a label on the top.  In this example (Listing 1.1), the columns are labelled PID, TTY, TIME and CMD.  This is the most basic invocation of the ps command, and the output is minimal.  If you start adding options, such as doing ps aux, (where you will get you a listing of all the processes on the system using BSD style syntax) you will get quite a bit more text to sift through.  But what if you are only after a certain term, such as tty, for example in the ps aux listing?

Tuesday, August 4, 2009

Find gotcha

Not too sure if I can call this a bonafide 'gotcha,' but it is something to keep in mind.

It is a good idea to occasionally check your Unix system for orphaned files. Normally you do so by using find with the -nouser and -nogroup filters. You could do two separate searches, one for -nouser, and then one for -nogroup, but typically the two are combined in one find command. Now here is the gotcha:

find / -nouser -nogroup -print

If you search find "-nouser -nogroup" on Google you likely find some examples like the one above. The problem with it is that there is an implied and when two or more filters are used as in the example. It is the same as doing the following (explicitly):

find / -nouser -a -nogroup -print
or:
find / -nouser -and -nogroup -print

The examples above will only 'find' files that belong to 'nouser' and 'nogroup.' If a file matches -nouser, but not -nogroup, find will not display it. If a file exists that matches -nogroup, but not -nouser, it will not display. Find will only return results that meet both criteria. In order to find all orphaned files, you want to do an or:

find / -nouser -o -nogroup -print

Now go have some fun tracking down those orphaned files!

Monday, August 3, 2009

Getting rid of troublesome files with GNU find.

Ok, so this isn't that much of a problem these days for those who are running a GUI, but what about when X isn't available? Consider the following:

kermit@fastbox ~/tmp/work2 $ ls -l
total 4
-rw-r--r-- 1 kermit kermit 37 2009-08-03 21:04 -pesky

I got that file by doing:

kermit@fastbox ~/tmp/work2 $ echo "Haha, sucker"\! "Try and get rid of me"\! > -pesky

Now try and issue the rm command on the file -pesky and you will find that it doesn't work so well. What can you do? Well, you can do what Bash tells you, and do:

kermit@fastbox ~/tmp/work2 $ rm -f ./-pesky

Or if you read the man page for rm, you would know that you can also do:

kermit@fastbox ~/tmp/work2 $ rm -f -- -pesky #The '--' tells the shell there are no more options following.

But there is another interesting way to do this operation, and it will work with other kinds of problematic, persistent files as well. We will use find to nuke the file. First, you need to find the inode number of the file, by using ls with the -i flag:

kermit@fastbox ~/tmp/work2 $ ls -li
total 4
8339920 -rw-r--r-- 1 kermit kermit 37 2009-08-03 20:57 -pesky

In this case, the inode number is 8339920. Now we can tell find to find the file with that number. Once it finds it, we can -exec /bin/rm -f and remove it:

kermit@fastbox ~/tmp/work2 $ find . -inum 8339920 -exec /bin/rm -f {} \;
kermit@fastbox ~/tmp/work2 $ ls -l
total 0