Tuesday, December 18, 2007

Part 1: How to work with Access Control Lists from the Command Line

The basic Linux permission model lets you specify permissions for the file's owner and group, and all others. This article assumes that you are familiar with the basic permissions, and know how to set them. The Access Control List (ACL) feature extends the model to allow much finer control: you can specify permissions for each individual user and group defined in your system.

Consider this scenario: your server supports multiple office departments: Sales, Marketing, and Helpdesk. Each department has a manager, and one or more staff members.

You define a group for each department that comprises of its manager and staff members: sales-g, marketing-g, and helpdesk-g. Then, you also define a managers only group: managers-g.

It is normal that some departments need to share files among each other, but not with all departments. For instance, Sales needs to share a file with Marketing, but not with HelpDesk. To set that up using only the basic permissions, you can define yet more groups: sales-marketing-g, sales-marketing-managers-g, etc.

Alternatively, you can use ACL to assign permissions to individual group and user.

Before you can use ACL, you must explicitly turn it on for the partitions you want to have the ACL feature available.

As root, edit /etc/fstab. Find the partition that you want ACL enabled, and add the mount option acl.
/dev/mapper/star-home /home ext3  defaults,acl 0 2


Next, assuming that your partition is already mounted, then either reboot the system, or better yet, remount dynamically:
mount -o remount,acl /home


Next, you need to make sure that you have 2 ACL utilities installed: getfacl, and setfacl.

On a Debian system, install the utilities like this:
$ apt-get install acl


Note: eiciel is a GUI-based utility that can both get and set ACLs. It adds a new Access Control List tab to the Properties view in Nautilus. You can also run eiciel on its own, and edit the ACL of any file or directory.

Now, you are ready to tackle ACL.

Let's start simple: you have a file /home/peter/targets.txt that you want to share between sales-g, marketing-g, and an user named george.
$ cd /home/peter;ls -l
total 64
-rw-r--r-- 1 peter peter 60097 2007-12-08 10:55 targets.txt


Use setfacl -m to set Access Control List for the file.
$ setfacl -m group:sales-g:rw-   targets.txt


The group:sales-g:rw- parameter specifies Read and Write permissions (rw) for the group: sales-g.

To enable the Read/Write permissions for the Marketing department, and george the user:
$ setfacl -m group:marketing-g:rw-,user:george:rw- targets.txt
$ ls -l
total 68
-rw-rw-r--+ 1 peter peter 60097 2007-12-08 10:55 targets.txt


Note that ls -l does not display the actual ACL of a file. It only tells you that ACL is defined for that file: a plus character (+) is displayed to the right of the permissions.

To examine the actual ACL, run getfacl.

$ getfacl targets.txt
# file: targets.txt
# owner: peter
# group: peter
user::rw-
user:george:rw-
group::r--
group:sales-g:rw-
group:marketing-g:rw-
mask::rw-
other::r--


Part 2 of this article describes how to define ACL for a directory. As you would expect, you can specify the read/write/execute permissions for any group or user on a directory. In addition, you can specify the DEFAULT permissions for any FILE created under this directory.

Saturday, December 8, 2007

How to Change Mount Options at Runtime

File systems need to be mounted on Linux before you can access the data on them. You can specify mount options such as whether the file system is Read Only or Read/Write, and whether to support Access Control List, etc.

To see what file systems are currently mounted, where, and with what options, issue the mount command without arguments:
$ mount
...
/dev/hda5 on /home type ext3 (rw,acl)
...


Recently, I wanted to tell the file system not to track the last access time (atime) of files under /home. I did not have any good use for the last access time. So, I opted to disable its tracking to reduce disk activity and save a few watts. This is accomplished through adding the mount option noatime.

To change the mount option for /home:

  1. Edit /etc/fstab as root.
  2. Add the option noatime to the line that corresponds to /home:
    /dev/hda5 /home ext3    defaults,acl,noatime   0  2

  3. To make the change effective, you can either reboot (to which you sneer) or you can remount /home.

To remount a file system, say /home, with new mount options at run-time, issue a command like this:
$ mount -o  remount,noatime   /home

There you have it. You can now feel good about saving a few watts, and be the hero in saving the environment.

Saturday, December 1, 2007

How To Mount USB flash drive from Command Line

Mounting a USB flash drive in GNOME (or another Linux desktop environment) is as easy as plug and play. Yet, occasionally, you need to mount one on a server which does not run X, then you must know how to do it on the command line.

  1. Become root.

    $ sudo -s


  2. Plug in USB drive to a USB port.

  3. Identify the correct partition name corresponding to the USB drive.

    For my Debian system, it is sda, and partition 1.
    $ dmesg |grep -i 'SCSI device'
    ...
    SCSI device sda: 3903488 512-byte hdwr sectors (1999 MB)

    Alternatively,
     $ grep  SCSI /var/log/messages
    ...
    Dec 1 11:52:26 tiger kernel: SCSI device sda: 3903488 512-byte hdwr sectors (1999 MB)

  4. Mount the partition to an existing mount point (directory).

    $ mkdir -p /mnt/myusb
    $ mount -t vfat -o rw,users /dev/sda1 /mnt/myusb

    users give non-root users the ability to unmount the drive.

    You can verify the drive is indeed mounted as follows:
     $ mount

    You should see a line in the output that looks like:

    /dev/sda1 on /mnt/myusb type vfat (rw,noexec,nosuid,nodev)


To retrieve the USB drive:

  1. You must unmount the partition before physically unplugging the USB device.


    $ umount /mnt/myusb

    You can run the mount command again (with no argument) to verify that the volume is indeed mounted.

  2. Unplug USB drive.

Monday, November 26, 2007

Use of --parents flag in mkdir and cp

Occasionally, you want to create a directory structure several levels deep.
For example, /home/peter/status/2007/november.

Your first attempt may be something like this:
$ mkdir /home/peter/status/2007/november
mkdir: cannot create directory `/home/peter/status/2007/november':
No such file or directory


The problem is that the intermediate directories (status and 2007) do not exist.

The following will work, but it is quite clumsy.
$ cd /home/peter; mkdir status
$ cd status; mkdir 2007
$ cd 2007; mkdir november


A much shorter way is simply:
$ mkdir --parents /home/peter/status/2007/november


With the --parents option, mkdir will actually create the intermediate parent directories if needed.

-p is the short equivalent of --parent for the mkdir command.

When the time comes to create the december directory, you can issue this:
$ mkdir -p /home/peter/status/2007/december


Although you have specified the -p (--parents) option, and the parent
directory structure already exists, it will quietly create the december
directory below it. This is just what we expect.


To check your results, do a ls -R (recursively list the directory)
$ cd /home/peter; ls -R status
status:
2007

status/2007:
december november

status/2007/december:

status/2007/november:


Let's create a file in /home/peter/status/2007/november.
 $ touch /home/peter/status/2007/november/nov12.txt

The above will create an empty file named nov12.txt.

Next, we will copy the nov12.txt file like this:
$ cd /home/peter
$ cp --parents status/2007/november/nov12.txt /home/peter/tmp


The --parents flag will cause the full path to be copied to tmp ("status/2007/november/nov12.txt")

$ cd /home/peter/tmp/
$ ls -R status
status:
2007

status/2007:
november

status/2007/november:
nov12.txt


How is cp --parents different from cp -r (recursive copy)?

$ cd /home/peter
$ cp -r status /home/peter/tmp


The recursive copy will have copied everything under status (including the contents of the december directory).

ls -R /home/peter/tmp/status
/home/peter/tmp/status:
2007

/home/peter/tmp/status/2007:
december november

/home/peter/tmp/status/2007/december:

/home/peter/tmp/status/2007/november:
nov12.txt

Tuesday, November 20, 2007

sudo hacks: making cd and redirection work

Suppose you want to run a command that requires root privileges. Conventional wisdom says don't login as root. Instead, login as a non-root user, and then sudo.
$ sudo 'cd /root/restricted'
Password:
sudo: cd /root/restricted: command not found
$

cd Not Found ?? That is RIGHT !

cd is a shell built-in command. It cannot be run in a child process. The child process simply cannot change the working directory of its parent shell process.

Redirection also does not work with sudo for the same reason (redirection being a shell "thing")
$ sudo 'ls /root/restricted >/root/out.txt'
sudo: ls /root/restricted >/root/out.txt: command not found
$


The workaround in both cases is to execute the command in a subshell.

$ sudo sh -c 'cd /root/restricted'

$ sudo sh -c 'ls /root/restricted >/root/out.txt'

Monday, November 19, 2007

How to Look Up a Process

You can look up a process in many ways. Often, you have the name of a daemon, command, or a program, and you want to know its process ID. For example, you may want to find the process ID of firefox.

  • pgrep

    $ pgrep firefox
    4559


    You do not need to specify the complete name.

    $ pgrep fox
    4559


    Because of the partial matching, it is prudent to have pgrep report both the process ID and the matching name:

    $ pgrep -l fox
    4559 firefox-bin


  • ps
    $ ps aux |grep fox 
    peter 4559 4.0 8.7 211680 84668 ? Sl 08:58 6:20 /usr/lib/iceweasel/firefox-bin -a firefox
    root 10611 0.0 0.0 2848 696 pts/0 R+ 11:36 0:00 grep fox


    Alternatively,
    $ ps -ef |grep fox
    peter 4559 1 4 08:58 ? 00:06:26 /usr/lib/iceweasel/firefox-bin -a firefox
    root 10645 8518 0 11:38 pts/0 00:00:00 grep fox


    The second output line for each of the 2 commands refers to the grep itself, and should be ignored.


The pgrep and the ps approaches can be adjusted to look up a process using other criteria besides the name.

For example, to look up all processes being executed by an user ID (0 = root):


  • $ pgrep -lu 0
    pgrep -lu 0
    1 init
    2 migration/0
    3 ksoftirqd/0
    4 events/0
    5 khelper
    6 kthread
    9 kblockd/0
    ....


  • $ ps -ef |grep root 
    root 1 0 0 08:56 ? 00:00:01 init [2]
    root 2 1 0 08:56 ? 00:00:00 [migration/0]
    root 3 1 0 08:56 ? 00:00:00 [ksoftirqd/0]
    root 4 1 0 08:56 ? 00:00:00 [events/0]
    root 5 1 0 08:56 ? 00:00:00 [khelper]
    root 6 1 0 08:56 ? 00:00:00 [kthread]
    root 9 6 0 08:56 ? 00:00:00 [kblockd/0]
    ...

    The grep command will match root along anywhere on the output line. This is sufficient for most casual command line lookup of processes. Of course, you can write to your heart's content a pattern-matching awk/perl script to only output lines that have root in the user name field.


For details, please read the pgrep and ps man pages.

Tuesday, November 13, 2007

How to Scroll the Command Window

How many times have you been annoyed by the command output spanning over the length of the window? If the window is in the X-Window environment, then you could use the scroll bars to scroll back. What if this is your console window, and it does not have scroll bars?

Sure, if only you had remembered, you could have piped the command to the less command. For example,
ps -ef |less


It turns out that you can scroll the bash command window.

To scroll up, hit Shift-Up.

To scroll down, hit Shift-Down.

Simple? Yes. And Effective !!

Saturday, November 10, 2007

Get into the right groups

In Linux, belonging to the right group gives you permission to use restricted-access resources.

When you create a new user, by default,

$ useradd -m george
$ passwd george
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully

Of course, you could have done the above using the wizard-styled adduser command.

Now, see what default groups george is in:

$ groups george
george : george

Poor george: he is a loner: being a group of oneself.

george may one day try to use some peripheral devices like the CDROM drive, USB drive, or floppy drive, and discovers that he simply cannot.

What do you do?

First, make sure that for pre-configured drives like the CDROM and floppy drives, the user option is specified. The default option is nouser which restricts access to root only.

cat /etc/fstab
...
/dev/hdb        /media/cdrom0   udf,iso9660 user,noauto     0       0
/dev/fd0        /media/floppy0  auto        rw,user,noauto  0       0
...

If the drive is configured correctly, then determine if george is in the right groups. The easiest way is to reference some user whom you know can access the target devices.

$ groups peter
peter : peter dialout cdrom floppy audio video plugdev netdev powerdev

Most group names are self-explanatory. For USB thumb drives, make sure that george is in plugdev.

To add george to the right groups:

usermod -aG  cdroom,floppy,plugdev  george

usermod -aG appends the new groups to george's existing groups.

$ groups george
george : george cdrom floppy plugdev

Remember this: if you are not in the right group, you don't get invited to the right parties ....

Click here for an updated post about group membership.

Tuesday, November 6, 2007

Tail multiple files


In an earlier post, I discussed 2 commands for continuously displaying the contents of a file: tail -f and less. I mentioned that with less, you can scroll back, perform searches, and, in general, use all the interactive commands that come with less.

There is (at least) one scenario where tail -f is more appropriate than less:
when you need to tail more than 1 file.
$ tail -f /var/log/messages    /var/log/mail.log
==> /var/log/messages <==
Nov 6 20:17:54 tiger -- MARK --
Nov 6 20:38:04 tiger -- MARK --

==> /var/log/mail.log <==
Nov 5 18:04:51 tiger sendmail[3090]: gethostbyaddr(192.168.0.102) failed: 3
Nov 5 18:04:52 tiger sendmail[3192]: gethostbyaddr(192.168.0.102) failed: 3
Nov 5 18:05:07 tiger sm-mta[3733]: starting daemon (8.13.8): SMTP+queueing@00:1 0:00
Nov 5 18:05:07 tiger sm-mta[3733]: restarting /usr/sbin/sendmail-mta due to sig nal

==> /var/log/messages <==
Nov 6 20:58:05 tiger -- MARK --


The contents of each file are interspersed throughout the output, making it somewhat hard to read.

Alternatively, you can use another tool named multitail to tail multiple files. Multitail divides the console into multiple windows: one for each file.
multitail  /var/log/messages  /var/log/mail.log



To scroll back, type b. Then, select the file to scroll. The selected file will be displayed in a new window. Now, you can use the arrow keys as well as the PageUp/PageDown keys to scroll. To exit the scroll window, type x.

I find multitail a bit clumsy to use. For simple log file viewing I tend to stick with tail -f.

Note that multitail may not be installed by default in your Linux distribution.

Keeping Command History across Multiple Sessions

The bash shell maintains a history of the commands you entered. You can re-execute a command by recalling it from the history, without having to re-type it.

The command history is stored in a file, specified by an environment variable.
$ echo $HISTFILE
/home/peter/.bash_history

The maximum number of commands that it will save depends on the value of this environment variable:
$ echo $HISTSIZE
500

Life is simple if we operate on a single shell session at any given time. If you have 2 simultaneous sessions, you may be surprised that the history does not have the commands you expect.

The default behavior is that the command history is saved ONLY on session exit. Moreover, the existing contents in the history are overwritten by the new contents.

Assuming you already have a session running, opening a second session will not have the latest commands from the first session. This is because the first shell hasn’t exited yet. Ultimately, the contents of the history file depends on which session exits last, hence overwriting the commands from the session that finishes earlier.

This can become quite confusing.

The remedy is simple. Change the history behavior as follows:

  1. Append commands to the history file, rather than overwrite it.
    $ shopt -s histappend

  2. Save each command right after it has been executed, not at the end of the session.
    $ PROMPT_COMMAND='history -a'


Insert the 2 statements into ~/.bashrc
shopt -s histappend
PROMPT_COMMAND='history -a'

Note: If the PROMPT_COMMAND is already initialized, then you probably want to concatenate the history -a part to what is already there.

To determine if PROMPT_COMMAND has a value:
echo $PROMPT_COMMAND

To concatenate:
PROMPT_COMMAND="history -a;$PROMPT_COMMAND"

Thursday, November 1, 2007

Log watching using tail or less

Log files typically grow in size, with the latest contents appended to the end of the log. I often need to watch a log file in live action, for error detection.

The command tail -f will display the last 10 lines of a file, and then continuously wait for new lines, and display them as they appear.
$ tail -f /var/log/messages


If you want to see more than ten lines at the outset, specify the new number (say 50 lines) like this:
$ tail -50   -f /var/log/messages


The tail command is fast and simple. But if you want more than just following a file (e.g., scrolling and searching), then less may be the command for you.
$ less /var/log/messages

Press Shift-F. This will take you to the end of the file, and continuously display new contents. In other words, it behaves just like tail -f.

To start less in the tail mode (thanks to Seth Milliken for this tip), execute:
$ less +F /var/log/messages


To scroll backwards, you must first exit the follow mode by pressing Control-c. Then, you can scroll back by pressing b. In fact, all the less commands are available to you once you are in the regular less mode. You can start a search by typing / followed by the string you want to search for.

Happy Log Watching !!!

P.S.
Related articles on tailing files:
Tail multiple files
Two additional ways to tail a log file

Tuesday, October 30, 2007

grep with color output

grep is capable of color-highlighting the matched string in its output. But, by default, that option is turned off.

$ grep abc a_file.txt
abcdef


There are 3 color options available to you:
  • --color=auto
  • --color=always
  • --color=never

With color=always, it colors the matched string.
$ grep --color=always  abc  a_file.txt
abcdef

Quite often, you want to page through the output:
$ grep --color=always  abc  a_file.txt |less 
ESC[01;31mabcESC[00mdef
(END)

The problem is that less does not understand those control characters, by default. You need to use the -R parameter.
$ grep --color=always  abc  a_file.txt |less -R
abcdef

Alternatively, use more.
$ grep --color=always  abc  a_file.txt | more 
abcdef

Another problematic scenario is when you want to save the grep output to a file. The output file will contain those control characters.

$ grep --color=always  abc  a_file.txt > myoutput.txt
$ less myoutput.txt
ESC[01;31mabcESC[00mdef
myoutput.txt (END)

With color=auto, it displays color in the output unless the output is piped to a command, or redirected to a file.

Lastly, you can specify the color parameter in a grep-specific environment variable. Then, you don't have to enter it in the command line.
$ export GREP_OPTIONS='--color=always' 


So, go ahead, and add color to your Linux world.

P.S. Additional grep articles from this blog:

Monday, October 22, 2007

The find / xargs Linux command-pipe

My task at hand is to delete all backup files ("*~") located anywhere in my home directory hierarchy.

$ find /home/peter -name *~ |xargs rm

This works reasonably well, but some targeted backup files are actually not deleted, namely:
  1. backup files in a sub-directory that is symbolically linked.
  2. backup files that have spaces in their file name or path name.

In addition, the xargs command handles zero argument poorly. If no match is found by the find command, xargs is not smart enough to terminate right away, but will still try to execute the target command (rm) in some way.

$ find /home/peter -name no-such-thing* |xargs rm
rm: missing operand


Symbolic Links

find does not follow symbolic links, by default. To make it follow symbolic links, add the -L parameter.

$ find -L /home/peter -name *~ |xargs rm

Names with spaces

xargs splits up its input arguments at spaces (and newlines). If a file name (or path name) has spaces in it, e.g., "can not do this.pdf", xargs will misinterpret it and thinks there are multiple files.

The solution is to invoke xargs with the -0 (zero) parameter. xargs will separate filenames by NUL instead of whitespace. Also, the find command needs the -print0 parameter: this puts a NUL between filenames instead of a newline.

Note that the -print0 parameter must be put last in find.
$ find /home/peter -name *~ -print0 |xargs -0 rm


Zero argument

Use the -r flag with xargs. If stdin is empty, xargs will not run the command, and exit.

Putting it altogether, the command I will use for my task is:

$ find -L /home/peter -name *~ -print0 |xargs -0 -r rm

Saturday, October 20, 2007

Crunch numbers



You can crunch numbers on the command line using the command "bc". Instead of firing up a GUI-based calculator application, you can do a quick compute right on the command line.

Running bc will put you in interactive mode by default. You type in statements, and it returns the answer.
$ bc
5 * 3
15
$

The same calculation can be done non-interactively.
$ echo '5 * 3' | bc
15


By default, division returns truncated whole numbers.
$ bc
10 / 3
3

You can define the number of decimal places you want in the answer. This is the "scale".
$ bc
scale=2
10 / 3
3.33

Alternatively, you can invoke the bc command with -l. This preloads the math library and the default scale is set to 20.
$ bc -l
10 / 3
3.33333333333333333333

You can convert a number from one base (ibase) to another base (obase). The default ibase and obase are base 10.

To convert the number 255 in base 10 to base 2,
$echo 'obase=2; 255' | bc
11111111

In reverse,
$ echo 'ibase=2; 11111111' | bc
255

Shred it!




Have a top-secret file that you want to delete? A file that you don't want to recover by you or anyone else?

Use the shred command:
#shred

By default, the shred overwrites the target file 25 times. But, it does not delete the file per se.

I usually want to overwrite AND delete it.

#shred -uvz -n 50 topsecret.txt

The -u flag will actually remove the file after overwriting it.
The -n specifies the number of overwriting passes: 50 in this example.
The -z flag will add a pass at the end to zero out the data.

Add in a -v (verbose) flag to see the shredding in action.

Disclaimer: Please read the man page of the shred command. Shred is not effective against certain types of file systems, journaling file systems being the notable example. Shred is NOT effective for ext3, (the default file system for most modern Linux distributions), if your ext3 partition is mounted in data=journal mode. In the journal mode, file data in addition to just metadata are stored in the journal. According to the man page, shred works as usual in both the data=ordered (default) and data=writeback modes.

If you are not sure about the data mode for your ext3 partitions, display /etc/fstab and look for data= for your ext3 partitions.
$more /etc/fstab

Sunday, October 14, 2007

Dictionary Lookup via Command Line


#curl dict://dict.org/d:YourWord
To help you remember, d: stands for DEFINE.

For example, to look up the word "bash", (all output in this article are greatly abbreviated for clarity)
# curl dict://dict.org/d:bash
151 "Bash" gcide "The Collaborative International Dictionary of English v.0.48"
Bash \Bash\, n.
1. a forceful blow, especially one that does damage to its
target.
[PJC]
2. a elaborate or lively social gathering or party.
[PJC]


The dict.org web site supports 77 dictionaries. To list them:
#curl dict://dict.org/show:db

So, if you want to know the computer meaning of "bash", specify foldoc "The Free On-line Dictionary of Computing" like this:
#curl dict://dict.org/d:bash:foldoc
151 "bash" foldoc "The Free On-line Dictionary of Computing (27 SEP 03)"
bash
Bourne Again SHell. {GNU}'s {command interpreter} for {Unix}.
Bash is a {Posix}-compatible {shell} with full {Bourne shell}
syntax, and some {C shell} commands built in. The Bourne
Again Shell supports {Emacs}-style command-line editing, job
control, functions, and on-line help. Written by Brian Fox of
{UCSB}.

To display results from all libraries, do this:
#curl dict://dict.org/d:bash:*


Fuzzy matching is also possible. Replace the "d" or Define command with "m" which stands for MATCH.
#curl dict://dict.org/m:bash

With the match command, you can also specify the strategy such as exact, prefix, suffix, or even soundex.

#curl dict://dict.org/m:bash::prefix
gcide "Bash"
gcide "Bashed"
gcide "Bashful"
gcide "bashful Billy"


To list all supported strategies:
#curl dict://dict.org/show:strat

Saturday, October 13, 2007

Recalling command history

The bash shell has a command history. You can repeat a command which you executed before by specifying the command number, e.g., !398 to run the command numbered 398 in the history.

Alternatively, you can specify a partial search string like this: !rm

Either way, the corresponding command is executed right away. Kind of dangerous, you say??

To be on the safe way, you want to see the exact command before the command is executed.

Just add :p to the end, like
!398:p
!rm:p

It will just print out the command that matched the command number (or the search string), but not execute it.

If it is really the command you want, just do !! to run the last command.

Better safe than sorry.

Thursday, October 11, 2007

You can always have the Last Word In ..

!$ is a handy shorthand for the last word in the previous command.

At first, it may not seem that useful.

But wait, ...

cd somedir
cp some_file_a /some/long/dir/path/some_file_b

Now you want to edit some_file_b

Just type
vi !$

That translates to vi /some/long/dir/path/some_file_b

It saves quite a bit of typing. Not bad.

Tuesday, October 9, 2007

More context with less

less is a text file viewer. By default, it will print out one screenful of file contents at a time, and wait for you to tell it what to do next. Scroll forward? Backward? Search for a string?

Sometimes, when I scroll through an unfamiliar file, I don't know where I am in the file. Am I near the beginning, or the end? Am I in the middle?

To get some context, you can specify some run-time options for the less command.

#less -mN somefile.txt

-m will display the percentage complete at the bottom of the screen.
-N will display line numbers.

Instead of typing out the command-line options every time, you can specify the options in an environment variable.

#export LESS="-mN"

Finally, put the above command in your .bashrc file.

Sunday, October 7, 2007

Command Line editing: emacs or vi shortcuts

You can edit your command line using emacs style shortcuts. For example, to go to the beginning of the command line, enter Control-a via keyboard input; to go to the end of line, Control-e. If you are a emacs user like me, you feel right at home.


One time, I logged in to someone else's Linux machine, and arrived at the bash shell. To my surprise, a Control-a did not take me to the start of line. Instead, I saw:

$ ./somecommand ^A^A


It did not seem to understand my emacs-styled keyboard shortcuts.

It turns out that for the bash shell, you can use other styles of command line edits besides the emacs style. Some users prefer the vi/vim style of command line edits.

To switch, set the relevant shell option. In the above example, to switch to the emacs style, type:

$ set -o emacs

If you want to switch from the default emacs to the vi style, type:


$ set -o vi



For the vi style of command line edits, you must first press the Esc key to enter the command mode. Then, you can enter the command, e.g., the ^ key to go to the beginning of the line, or the $ key to the end of the line. To return to regular typing mode, type the letter i for insert, or a for append.

Saturday, October 6, 2007

My #1 beloved tool: emacs

It is fitting that my first post is about the tool I love the most: GNU emacs. It is the text editor, plus a lot more.

Normally, when you just run emacs, it will load your initialization file (.emacs). But, what if you just want to do something quick, and don't want to wait the extra couple of seconds for emacs to load all these other stuff in your init file?

Just run emacs with the -q option. You will have a bare-bone emacs.