More 2 Cent Tips & Tricks Issue 24

#### "Linux Gazette...making Linux just a little more fun! "

# More 2¢ Tips!

Send Linux Tips and Tricks to gazette@ssc.com

### Contents:

- Followup to PostScript and VC Key Sequences (LG#23)
- PostScript $0.02 follow-up
- Yet another cheap tip
- 2 cent tip - dosemu
- Re: 2c Tip "Finding What You Want with find"
- Re: Finding What You Want with find
- Finding What You Want with find Part III
- More on finding
- Another way to find
- Yet another way to find
- A final(?) way to find
- Re: I need some help
- Spinning Down Unused HDs
- LG Tips and Tricks (Netscape)
- Easter Eggs in Netscape
- Calculator Tip
- Security script
- Controlling cron.hourly
- Syslog and ping

### Followup to PostScript and VC Key Sequences (LG#23)

Date: Thu, 4 Dec 1997 16:43:47 +0000 (GMT)
From: Ivan Griffin ivan.griffin@ul.ie

I just wanted to point out that some of my 2cent tips in Issue 23 of the Linux Gazettte (December, 1997) were a little funky in their appearance.

While it doesn't really matter at all with the VC key sequences, it may affect someone's understanding of the bad (imho) PostScript generated by the Microsoft PS driver.

In this, the PostScript should have been pre-formatted using the appropriate HTML tags. Basically, the line

        30000 VM?

Is on its own, and not part of any other line. All that you have to do to remove this artificial restriction on viewing/converting the PostScript with ghostscript is to delete this line.

On another note, someone asked me where those key sequences come from. If you check either keyboard.c or keyb_m68k.c, you will find an array of function pointers called spec_fn_table[].

This array contains a list of functions to execute when certain key combinations are received... The key combinations listed in the 2cent tips execute the functions show_state(), show_mem() and show_regs()

You will find the source for function show_state() in /usr/src/linux/kernel/sched.c

show_mem() is in /usr/src/linux/arch/i386/mm/init.c

and show_regs() is in /usr/src/linux/arch/i386/kernel/process.c

Best Regards,
Ivan.

### PostScript $0.02 follow-up

Date: Wed, 3 Dec 1997 13:51:48 -0500 (EST)
From: Kyle Ferrio kbf@phy.duke.edu

In the December issue of LG, Ivan Griffin suggests using pstops from the psutils package to accomplish two-up printing, gives a helpful example for A4 paper, and points out that the command line needs to be tweaked for US letter. If you're using US letter paper, then psnup (also part of psutils) already does the job nicely with no uncomfortable thinking. It might even work for A4, but I haven't checked. The psutils are generally very handy, so folks might want to have a look. An RPM is available in /contrib at ftp.redhat.com, for instance. Be advised that there seem to be at least two very distinct packages called psutils floating around Net-space.

### Yet another cheap tip.

Date: Sun, 30 Nov 1997 03:48:40 -0800 (PST)
From: Gary Johnson gjohnson@season.com

Sorry if it has been mentioned before, I thought I would throw it in the Gazette pile just in case it hasn't . . .

Cat proof keyboard.

Switching to an unused virtual console is a quick way to blank the screen and disable the keyboard. To make one available try

            setterm -clear > /dev/tty12

on startup. ALT F12 flips to it, or ALT CTRL F12 from X. Because there (probably) isn't a login running on that VC it doesn't do much, which can be a feature. A smart cat may still luck into a troublesome key sequence.

### 2 cent tip - dosemu

Date: Fri, 5 Dec 1997 00:55:55 -0500
From: Joey Hess joey@kitenet.net

I occasionally use dosemu, mainly to run some games I can't live without, but I hate seeing the C:\> prompt. So I thought it'd be nice if there were a way to tell dosemu what dos command to run, and it would run that command on bootup. Here's a perl script that does just that. Read the comments at the top, they explain some changes you need to make on the dos side of this. The basic idea is, make a ~/dos_do.bat file, that contains the command you want to run, and use lredir to let dosemu see your home directory. Then run the batch file.

    #!/usr/bin/perl
    #
    # This runs dosemu.
    #
    # Any parameters psecified after "--" will be passed in to dosemu to be
    # run as dos commands.
    #
    # Setup: add to autoexec.emu:
    #       lredir.com h: linux\fs\${home}
    #       if exist h:\dos_do.bat call h:\dos_do.bat
    #
    # GPL Copyright 1996, 1997 Joey Hess

    # Split params into dosemu parameters and dos commands.
    while ($a=shift @ARGV) {
    	if ($a=~m/--/ ne undef) { last }
    	$dosemu_command_line.="$a ";
    }
    $dos_command_line=join(' ',@ARGV);
    $dos_command_line=~s/;/\r\n/g;

    open (OUT,">$ENV{HOME}/dos_do.bat") || exit print "$ENV{HOME}/dos_do.bat:
    $!";
    if ($dos_command_line) {
    	print OUT "$dos_command_line\r\n"; # note dos CR LF
    	print OUT "exitemu\r\n";
    }
    close OUT;
    system "/usr/bin/dos $dosemu_command_line";
    unlink "$ENV{HOME}/dos_do.bat";

### Re: 2c Tip "Finding What You Want with find"

Date: Wed, 03 Dec 1997 16:03:30 +0100
From: Mike Neuhauser mike@gams.co.at

Jon Rabone, jkr@camcon.co.uk, wrote in the December 97 issue of LG:

> In the October 97 issue, Dave Nelson suggests using
>`find . -type f -exec grep "string" /dev/null {} \;`
> to persuade grep to print the filenames that it finds the search
> expression in. This starts up a grep for each file, however. A
> shorter and more efficient way of doing it uses backticks:
>
>`grep "string" `find . -type f``
>
> Note however, that if the find matches a large number of files you
> may exceed a command line buffer in the shell and cause it to complain.

To avoid an overflow of the command line buffer use:

            find . -type f | xargs grep "string"

This may give problems if filenames contain white space (e.g. touch "test file") -- to avoid use:

            find . -type f -print0 | xargs -0 grep "string"

Note also that find doesn't follow symbolic links to directories per default. Using find with the option -follow does the trick (find . -follow ...).

### Re: Finding What You Want with find

Date: 5 Dec 1997 17:47:50 -0000
From: Dale K. Hawkins dhawkins@mines.edu

`find . -type f -exec grep "string" /dev/null {} \;`

That is how I used to run things too, but a friend showed me the xargs program. Very nice. So one could turn the above statement to something like:

    find . -type f | xargs fgrep "string" /dev/null

Again, the /dev/null will force the name of the file to be printed (in the unlikely case that find only found one file name). This has the benefit of not invoking a new grep process each time.

But for a really slick (and much faster search) try this:

    locate $PWD | grep "^$PWD" |xargs fgrep "string" /dev/null

This assumes that your locate database is current for the directory to be searched. It does have a problem though: it tries to grep everything, including directories!

    locate $PWD | grep "^$PWD" |xargs -ifilename sh -c \
      "if [ -f filename ]; then echo filename; fi " | \
      xargs fgrep "string" /dev/null

And as an exercise for the reader: Take a look at lesspipe.sh (if it is installed; download it otherwise!) See if you can create a shell script called supercat (or something) which preprocesses the input to prevent grep'ing binary files, etc.

You gotta love UNIX and especially Linux!

-Dale K. Hawkins

### Finding What You Want with find Part III

Date: Thu, 11 Dec 1997 17:12:46 +0100 (MET)
From: Axel Dietrich Axel.Dietrich@neuroinformatik.ruhr-uni-bochum.de

>In the October 97 issue, Dave Nelson suggests using
>
>`find . -type f -exec grep "string" /dev/null {} \;`
>
>to persuade grep to print the filenames that it finds the search
>expression in.

Besides Jon Rabone's "shorter and more efficient" version in the December 97 issue using backticks:

      grep "string" `find . -type f`

the following variant can be used without the danger of exceeding a command line buffer limit:

      find . -type f -exec grep -l "string" {} \;

The "-l" switch tells grep to show the name of the file in which "string" was found.

To limit such a search on selected files I use a combination of the -type and -name switches.

      find . \( -type f -name "*\.html" \) -exec grep -l "string" {} \;

This searches in all files with the suffix "html" for the string "string" and outputs the name(s) of the file(s) in which "string" was found.

Axel

### More on finding

Date: Tue, 16 Dec 1997 14:12:57 +0100 (MET)
From: Alexander Larsson alla@lysator.liu.se

In the December 97 issue Jon Rabone wrote:

------------------------------------
This starts up a grep for each file, however. A shorter and more efficient way of doing it uses backticks:

    grep "string" `find . -type f`

Note however, that if the find matches a large number of files you may exceed a command line buffer in the shell and cause it to complain.
------------------------------------

A better way would be to use:

    find . -type f | xargs grep "string"

which starts up a new grep everytime the command line buffer is full.

/ Alex

### Another way to find

Date: Sat, 27 Dec 1997 12:06:47 -0500
From: rchandra@letter.com

In an article in the LG, it was suggested that, in order to cut down on having to fork(2)/exec(2) for each grep when you're searching through a tree of files, you use the shell's capability of command substitution (for the file names paramaters to the grep command) with "backquotes," "grave accents," "backticks," etc. as they are commonly called ("`"). In that little tidbit, it is noted that it has the limitation of the system-wide imposed limit on number of arguments, and I possibly think there might be a length issue as well (too many total bytes). Enter xargs(1).

The job of the xargs command is to read its stdin and use the resultant strings as arguments to some command prefix (such as "grep -n somestring"), much like backquotes work. However, the xargs program is "aware of" the limitations imposed by the system, and will run the command prefix as many times as necessary to exhaust the list provided on stdin, while on each run giving the command only the maximum number of arguments and the maximum byte count (?) that an exec(2) call can handle. Thus, provided that the program named in the command prefix follows the UNIX program protocol of iterating over its non-option arguments, one can search one, hundreds, thousands, even millions of files with a line like:

    find / -type f -print | xargs grep -n 'where is that string?'

As usual, consult your favorite source of documentation, such as your local man pages, for ways to get even craftier with xargs.

### Yet another way to find

Date: Mon, 29 Dec 1997 10:49:52 +0100
From: Guido Socher eedgus@aken104.eed.ericsson.se

In recent Linux Gazette issues there were a couple of ideas on how to recursively grep around files and directories. Very useful, but it can cause problems when you have binaries (e.g some executable) in the directories that contain somewhere the string that you are looking for. The result is most of the time an unusable terminal because some control character from the binary file has set it to graphics mode. There are, of course, ways to make the terminal readable again but the best is to avoid it in the first place.

Let's just remove the unprintable characters. They are unreadable anyway! The command

          sed -e 's/[^ -~][^ -~]*/ /g'

removes multiple occurrences of non printable/control characters and replaces them by a single space. The [^ -~] matches all characters not in the ASCII range from SPACE to Tilde. This command can be easily combined (using a pipe) with the find and grep. Here is a little script, I called it grepfind, that does it all:

    #!/bin/sh
    #save this in a file called grepfind and do a "chmod 755 grepfind"
    #
    if test $# = 0 -o "$1" = "-h" -o "$1" = "--help" ; then
    echo ' grepfind -- recursively descends directories and egrep all files '
    echo ''
    echo ' Usage: grepfind [--help][-h][start_directory] egrep_search_pattern'
    echo ''
    echo ' The current directory is used as start_directory if parameter'
    echo ' start_directory is omitted. The search is case insensitive.'
    echo ' Multiple occurrences of control characters are replaced by a single'
    echo ' space. This makes it possible to grep around in files that contain'
    echo ' binary data and strings without setting the terminal accidently '
    echo ' to graphics mode.'
    echo ''
    echo ' Example: grepfind /home "hello world" '
    else
    if [ "$2" = "" ]; then
    find . -type f -exec egrep -i "$1" /dev/null {} \; | sed -e 's/[^ -~][^
    -~]*/ /g'
    else
    if [ -d "$1" ];then
        find $1 -type f -exec egrep -i "$2" /dev/null {} \; | sed -e 's/[^
    -~][^ -~]*/ /g'
    else
        echo "ERROR: $1 is not a directory"
    fi
    fi
    fi
    #__END__OF_grepfind

### A final(?) way to find

Date: Wed, 31 Dec 1997 14:31:57 PST
From: Marty Leisner leisner@sdsp.mc.xerox.com

In the last few months, there's been a few letters (by Dave Nelson, Jon Rabone, some more) on how to grep with file names.

Instead of using the trick:

                    find . type f -exec grep "string" /dev/null {} \;

and other variatiants, or doing

                    grep "string" $(find . -type f)

1) use the -H option of grep 2.1 (to print file names, not in 2.0)
2) use xargs to overcome problems with buffer size

            find . -type f | xargs grep <pattern> -H

Marty

### Re: I need some help

Date: Sun, 7 Dec 1997 14:25:25 +0100 (MET)
From: Roland Smith rsmit06@ibm.net

Javier,

In response to your article in the mailbag of the dec. 97 Linux Gazette:

You need to set the environment variable MOZILLA to the directory containing Netscape's files.

There are two ways of doing this: You can type `export MOZILLA_HOME=/usr/local/netscape' every time you start your computer, or you can edit /etc/profile. This is a file read by the bash shell. Add the following to this file (assuming the Netscape stuff is in /usr/local/netscape):

    MOZILLA_HOME="/usr/local/netscape"
    export MOZILLA_HOME

You also need to add an entry for Netscape to your window-manager's initialization file, so it shows on the toolbar and/or menu. How to do this depends on the window manager you use.

If you're using fvwm2-95, add the following to the .fvwm2rc95 file in your home directory:

    # add to this menu:
    AddToMenu "Utilities" "Utilities" Title
    + "Netscape%mini-nscape.xpm%"   Exec netscape -geometry 931x683+54+9 &

Regards, Roland

### Spinning Down Unused HDs

Date: Mon, 08 Dec 1997 14:21:31 -0500
From: Peter S Galbraith galbraith@mixing.qc.dfo.ca

In the December issue of LG tips, you discuss the hdparm command to spin down disks. I tried this on my old SCSI disk:

    bash-2.01# hdparm -S6 /dev/sdb

    /dev/sdb:
     operation not supported on SCSI disks

Too bad! I use the `scsi-idle' kernel patch to do this very same thing on SCSI, and I was eager to try your trick to finally stop having to patch the kernel at evey upgrade.

Too bad it don't seem to work on SCSI disks (it's also strange that the man page doesn't say this...)

### LG Tips and Tricks (Netscape)

Date: Fri, 12 Dec 1997 02:56:16 -0600
From: Christian J Carlson carlson@means.net

* Date: Sun, 9 Nov 1997 22:00:31 +0000 (GMT)
* From: Ivan Griffin ivan.griffin@ul.ie
*
* These special URLs do interesting things in Netscape Navigator and Communicator.
*
* about:cache gives details on your cache
* about:global gives details about global history
* about:memory-cache
* about:image-cache
* about:document
* about:hype
* about:plugins
* about:editfilenew
*
* view-source:URL opens source window of the URL
*
* Ctrl-Alt-F take you to an interesting site :-)

This appeared in Linux Gazette, December 1997. There is one more way cool easter egg that's in Netscape.

First, type "about:mozilla" to get the Mozilla easter egg. Then, watch your "N" in the upper right hand corner of Netscape. Whenever you access a website, Mozilla himself will appear instead of the boring flying stars, etc. As far as I know, this has been in every version of Netscape since at least version 2.0. Of course, this only works in the Linux version (I don't know about other *nix versions) of Netscape, NOT Windows95 :).

Christian J. Carlson

### Easter Eggs in Netscape

Date: Tue, 30 Dec 1997 0:47:12 +1100 (EADT)
From: Michael Lake mikel@BlueSky.com.au

I have just been reading the Linux gazette Issue 23 about the easter eggs in Netscape and thought that I would try some URL's of my own. I am using Netscape 3.01 for Linux. A little experimentation found the following--

about:foo

The message that is returned is: Whatchew talkin' 'bout, Willis? Instead of foo you can use anything that is not understandable to Netscape.

A more interesting one that I tried is--

about:mozilla

This gives a very interesting quotation which I will leave to the reader to discover.

Enjoying the Linux Gazette immensely,

Best Regards,
Michael Lake
Sydney, Australia

### Calculator Tip

Date: Sun, 14 Dec 1997 19:23:55 -0500
From: Michael McLay mclay@nist.gov

The Issue #21 and #23 tips column gave tips for doing calculations without having to fire up a heavyweight GUI calculator. It is very handy to be able to do all the number entry through the command line, but I was surprised to see perl and awk used in the two examples. The bc has been around forever in Unix and would be the logical first choice to many oldtimers. And bc can do the calculations to any precision desired if that is important.

Another good option is Python. Python can be run in an interactive mode like bc, so previous calculations can saved as variables and reused. Python also can be built so that past lines can be edited using the standard GNU readline library editing operations. For instance, in the following interactive sequence the previous-line key will restore the last executed line to the prompt and the line edit keys, such as backward-char and delete can then be used to edit the line.

    ~: python
    Python 1.5b2 (#2, Dec 12 1997, 16:13:12)  [GCC 2.7.2] on linux2
    Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
    >>> a = (10+3)/7
    >>> a
    1
    >>> a = (10.+3)/7
    >>> a
    1.85714285714
    >>> a/32
    0.0580357142857
    >>> "it takes %7.2f percent" % a
    'it takes    1.86 percent'
    >>> "it takes %-7.2f percent" % a
    'it takes 1.86    percent'
    >>> from Numeric import *
    >>> b = array(arange(12))
    >>> b.shape = 3,4
    >>> b
    array([[ 0,  1,  2,  3],
           [ 4,  5,  6,  7],
           [ 8,  9, 10, 11]])
    >>> b/a
    array([[ 0.        ,  0.53846154,  1.07692308,  1.61538462],
           [ 2.15384615,  2.69230769,  3.23076923,  3.76923077],
           [ 4.30769231,  4.84615385,  5.38461538,  5.92307692]])
    >>>

This example also shows the Python Numeric[1] module being used at the command line. Any Python module that is installed with the interpreter can be imported and used in the interactive mode.

Of course if you want to make Python do a one-liner from the command line that is possible also:

    ~: python -c "print 34./33"
    1.0303030303

or to format the output:

    ~: python -c "print 'eat %3.4f %s' % (1.444e5/32,'more fish')"
    eat 4512.5000 more fish

[1] The Numeric module in this example is not built into the standard distribution. See the matrix-sig page for details on how to add it to the module library if you can't find it on your system.

### Security script

Date: Mon, 15 Dec 1997 20:49:53 -0600 (CST)
From: Corey G cgaff@interaccess.com

Often when I leave my machine connected to the Internet for prolonged periods I worry about hackers. I wanted a program that would know if a process was started by anyone, including root, that was not originally on the machine.

This caused me to program this script. I dont know if something similar exists but I have tested this very throughly and it works rather well. It can be frustrating at times when you are active on the machine but works very well for idle times.

HOW IT WORKS:

This scripts grabs all the processes when first invoked and saves them to a temporary file. After a default of 10 seconds the process table is checked against any new processes that were started. If these processes were not listed in the "TRUSTED_ITEMS" variable they will be killed immediately.

USAGE:

Once you have all the necessary processes running on your machine start the script as root. It will make the necessary directories on the machine in a safer place than just /tmp. I have created two variables named "TRUSTED_ITEMS" and "TRUSTED_USERS". These can be used to ignore some users or programs that you never want killed. Be careful since sometimes you will need to include more than one item for some programs. For example, if you dont want xterms killed you must add "xterm" and "bash" if you are running bash as your default shell.

Note: When testing this script make certain that nothing important is running. I take no blame for any wrong doing from this script.

To start the script:`nohup ./secmach &`

I am always looking for ways to improve this script so feel free to e-mail your comments or suggestions to me.

Good Luck !!!

    #!/bin/sh
    # Secmach - security program
    # v1.0  12-14-97
    # By: Corey Gaffney

    export PATH=/usr/bin:/bin:/sbin

    COUNTER=0
    LOCATION=/usr/secmach
    CHECK_TIME=10
    TRUSTED=/usr/secmach/trusted
    UNTRUSTED=/usr/secmach/untrusted
    DIFFKILL=/usr/secmach/diffkill
    TRUSTED_USERS="johndoe"
    TRUSTED_ITEMS="$TRUSTED_USERS|pppd|chat|netscape|xterm|egrep|ps|sed|secmach|awk"

    if [ ! -s $LOCATION ]
            then
            mkdir $LOCATION
            chmod 700 $LOCATION
            fi

    while :
    do
    COUNTER=`expr $COUNTER + 1`
    if [ $COUNTER -eq 1 ]
            then
            ps -aux | sed -e '1d' | awk '{print $2}' > $TRUSTED
    fi
            sleep $CHECK_TIME

    ps -aux | sed -e '1d' | egrep -v $TRUSTED_ITEMS | awk '{print $2}' >
    $UNTRUSTED
            diff $TRUSTED $UNTRUSTED > $DIFFKILL
            KILL=`grep ">" $DIFFKILL | awk '{print $2}'`
            kill -9 $KILL
    done

### Controlling cron.hourly

Date: Sun, 21 Dec 1997 10:36:16 -0500 (EST)
From: Jeff Johnson jbj@JBJ.ORG

According to Gary Turkington:
> I know this one of those *really* simple ones, but it's beating me. How
> do I stop the cron.hourly setup mailing a 'fortune' to root? This used
> to happen daily, no biggie, but when I upgraded to 5.0, its hourly.. spam
> :)

This is a variant of the "not a typewriter" error that causes loss of hair when using rlogin :-)

The analysis goes like this:

1) Cron runs a job an hourly job as root.
2) To run the job, a non-interactive (i.e. stdin/stdout are *not* connected
to a tty but to cron) shell is started.
3) The shell reads its init files: /etc/profile, ~/.bashrc, whatever.
4) The init files execute fortune.
5) The job is performed.
6) Cron detects output, so it mails it to root.

Fix by identifying which shell init file is executing fortune and avoiding fortune when not interactive. There are a couple of techniques for doing this, often by checking whether PS1 is set.

73 de Jeff

### Syslog and ping

Date: Tue, 30 Dec 1997 17:58:59 -0500 (EST)
From: Andrew Tucker andrew.tucker@kplus2.aces.k12.ct.us

Hi, this is a small hack I did to allow logging of users's use of ping through syslog. With more and more larger systems running Linux, and more and more situations of ICMP abuse, any shortcut a system administrator can use to prevent such abuse is helpful. Click here to dowload the scripts.

-- Andrew

Published in Linux Gazette Issue 24, January 1998

##### This page maintained by the Editor of Linux Gazette, gazette@ssc.com
Copyright © 1998 Specialized Systems Consultants, Inc.