Unix Tips & Tricks

by techtiptom

Here are a few pieces of Unix wisdom, picked up over the years…

You’ve done something that has completely screwed up your terminal. Everything you type is either invisible or incomprehensible. Try the following:

    $ ^C
    $ stty sane^J

If this doesn’t work, try:

    $ echo ^V^O

To determine what program dumped an anonymous core file, use gdb:

    $ gdb -core core
    Core was generated by `a.out'.
    Program terminated with signal 6, Abort trap.

If you are on a system without gdb, try the file command:

    $ file core
    core: ELF 32-bit LSB core file of 'a.out' (signal 6)

To create a vi macro that will wrap the current paragraph to a reasonable number of characters, add the following to your .exrc or .vimrc file:

    map Q {!} fmt -c -u^M

Now, when you press ‘Q’ in visual mode, the current paragraph will be wrapped to approximately 70 characters.

Due to the Unix concept of sparse files, you can create seemingly enormous files that in reality take next to no disk space. The following program will create a 305,419,897 byte file called ‘core’ that may result in you receiving a ‘cleanup’ email message from a less-than-seasoned Unix sysadmin even though it occupies virtually no real disk space.

    $ cat bigcore.c
    #include <fcntl.h>
    #include <unistd.h>

    int main(void) {
        int fd = open("core", O_CREAT|O_WRONLY|O_TRUNC, 0600);
        lseek(fd, 0x12345678, SEEK_SET);
        write(fd, "1", 1);
        return 0;

    $ cc -o bigcore bigcore.c
    $ ./bigcore
    $ ls -l core
    -rw-------  1 dmr  staff  305419897 May  1 03:50 core
    $ du -k core
    48      core

On older Unix systems, in particular those that don’t support MD5 password hashing, only the first 8 characters of a password are significant. If you use an 8 character password on these systems, you can type anything you want after the first 8 characters and it will be accepted by login. This allows you to type the first 8 characters of the password as usual, then have some fun. Enter a bunch of crap at superhuman speed, then enter the last few characters with your elbow. Then press backspace twice carefully and retype the characters with your other elbow. Etc….

When recursive copying, cp (cp -Rip, etc.) may not be the best tool for the job. For example, cp copies hard links as separate files, which is probably not what you want. To get a true copy of a directory, try:

    $ tar cf - <dir> | (cd <destdir>; tar xf -)

This will create an exact copy of ‘dir’ in ‘destdir’. The same principle can be used to create a recursive copy on a remote machine:

    $ tar cf - <dir> | ssh remotehost "(cd <destdir>; tar xf -)"

To list the files in another directory that match more than one pattern, it is easiest to do:

    $ ls -l /usr/local/foo/{*.conf,*.local,*.rc}

which is equivalent to:

    $ ls -l /usr/local/foo/*.conf /usr/local/foo/*.local /usr/local/foo/*.rc

This syntax is supported by (at least) bash, ksh, csh and sh.

You can extend this idea to make renaming files in another directory, for example, a little easier:

    $ mv -i /usr/local/foo/bar/baz/{stuff,stuff~}

A little insurance against running ‘rm -rf *’ in the wrong directory — create an empty file called -i in any critical directory:

    $ >-i


    $ touch -- -i

If the ‘rm -rf *’ command is issued in that directory, the shell will expand the ‘-i’ early on and go into interactive mode, thus giving you a chance to say ‘Whoa, that was close!’, which always sounds better than ‘Oh fsck!’.

This tip works because the -i option to rm will override any previous -f.

Be forewarned that this tip only protects against ‘rm -fr *’, i.e., files and directories in the current directory.

To remove the -i file (or any other file beginning with ‘-‘):

    $ rm ./-i


    $ rm -- -i

To return to the previous directory in ksh or bash, use:

    $ cd -

To use the last argument of the previous command line as an argument, use $_. For example:

    $ ls -l /usr/home/dmr/somefile
    $ vi $_

To make the up and down arrow keys work and thereby enable command line editing and recall in ksh, include the following lines in your ~/.profile:

    set -o emacs
    alias __A='^P'
    alias __D='^B'
    alias __B='^N'
    alias __C='^F'
    alias __H='^A'

You need to enter the actual control characters ^P, ^B, etc.