More 2 Cent Tips & Tricks Issue 10

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

## More 2¢ Tips!

### Contents:

- Tcl/TK Tips
- Perl Control M Trick
- Another Emacs Control M Trick
- XTerm Title Bar Function
- More on Commenting Code in VI
- More on X Term Title Trick 2
- Bash Quick Tip
- Neat Red Hat Management Trick
- More on Find and Alternatives
- Pico Control M Trick
- Yet Another Emacs Control M Trick

### Tcl/Tk Tips

Date: Tue, 03 Sep 1996 13:29:37 +0100
From: Liang Shing Ng <L.S.Ng@ecs.soton.ac.uk>
To: fiskjm@ctrvax.Vanderbilt.Edu
Subject: Tcl/Tk tips NOT IN Welch's Book

I see that you just got hooked with Tcl/Tk.

I found an *OLD* way of interfacing C program with Tk scripts, which is not documented in Welch's Book.

What is it? Pipe!

My C prog (parent) create two pipes to communicate with the Tk prog (child). The Tk prog only need to use stdin and stdout without knowing that this is controlled by the C prog. This provides a much easier way than the interface procedures described in Welch.

Attached here are my C prog and my Tk prog. If you think this is worth writing a full article, please let me know. I will do that for the Gazette. :)

Cheers
Liang-Shing Ng

Description: simple C and Tk prog pair showing how to read/write with each other. example of use: C may use this Tk for graphical interface. C does some image processing, then ask Tk to display it.

C Prog:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>

    int create_pipe(char *child, int opipe[2], int ipipe[2])
    {
        pid_t pid;

        /* Create output pipe and input pipe  */
        if (pipe (opipe)) {
            fprintf (stderr, "Pipe failed.\n");
            return EXIT_FAILURE;
        }
        if (pipe (ipipe)) {
            fprintf (stderr, "Pipe failed.\n");
            return EXIT_FAILURE;
        }

         /* Create the child process.  */
        pid = fork ();
        if (pid == (pid_t) 0) {
            /* This is the child process.  */
            /* Child stdin is opipe[0] */
            close(0);
            dup(opipe[0]);
            close(opipe[0]);
            /* Child stdout is ipipe[1] */
            close(1);
            dup(ipipe[1]);
            close(ipipe[1]);
            /* Closed unused FD */
            close(opipe[1]);
            close(ipipe[0]);
            execlp(child, child, NULL);
        }
        else if (pid < (pid_t) 0) {
            /* The fork failed.  */
            fprintf (stderr, "Fork failed.\n");
            return EXIT_FAILURE;
        }
        return pid;
    }

    main(int argc, char *argv[])
    {
        FILE *po, *pi;
        char s[128];
        pid_t pid;
        int opipe[2], ipipe[2];
        char buff[256];

        if (argc<2) {
            fprintf(stderr, "Tk display subprogram required.\n");
            fprintf(stderr, "Usage: %s display.tk\n", argv[0]);
            exit(1);
        }

        /* Change low level pipe FD to streams */
        pid=create_pipe(argv[1], opipe, ipipe);
        po=fdopen(opipe[1], "w");
        pi=fdopen(ipipe[0], "r");

        while (gets(s)!=NULL) {
            fprintf(po, "%.5s\n", s);
            fflush(po);
            fgets(buff, 256, pi);
            fprintf(stderr, "%s: %s", argv[0], buff);
        }

        /* Close output pipe and wait input pipe flush */
        fclose(po);
        fgets(buff, 256, pi);
        fprintf(stderr, "%s: %s", argv[0], buff);

        return 0;
    }

---
Tk prog

    #!/bin/sh
    # the next line restarts using wish \
    exec wish4.0 "$0" "$@"

    proc Reader { pipe } {
        gets $pipe line
        puts stderr "tk: $line"
        puts stdout "from tk: $line"
        flush stdout
    }

    image create photo imb -file a.ppm
    label .c -image imb
    pack .c
    wm geometry . +100+100
    update

    while { 1 } {

    if {[eof stdin]} {
        exit
    } else {
        fileevent stdin readable [ Reader stdin ]
    }

    }

### Perl Control M Trick

Date: Wed, 4 Sep 1996 17:02:40 -0700 (PDT)
From: Jonathan Gross <jong@ssc.com>
Subject: Perl Tip

I read the most recent issue of the gazette, and the control M issue caught my eye. Using vi or emacs is great, but if you have more than one file, you can do this:

    perl -pi.bak -e 's/\r//g;' filelist

FYI.

    -----------------------
    Jonathan (jong@ssc.com) finger me for my public key.
    Specialized Systems Consultants, 206-782-7733
    "A jewel mine of courtesies and a living casket of diplomacy"

### Another Emacs Control M Trick

Date: Thu, 05 Sep 1996 13:34:09 -0700
From: Earl Stutes <estutes@eas.com>
Subject: $.02 emacs tip

Here is the way I handle the ^M in files. Put this in your .emacs:

    (defun dos-unix ()
      (interactive)
      (goto-char (point-min))
      (while (search-forward "\r" nil t) (replace-match "")))
    (defun unix-dos ()
      (interactive)
      (goto-char (point-min))
      (while (search-forward "\n" nil t) (replace-match "\r\n")))

IP don't usually bind these to keys, but you certainly could. When you call the function M-xdos-unix, it will delete all of the delete all of the <CR> characters in the file. And of course the other function will put them back.

=eas=

### X Term Titlebar Function

Date: Fri, 06 Sep 1996 17:53:00 -0600
From: "Michael J. Hammel" <mjhammel@emass.com>
Subject: Gazette #9 comments -- xterm title bar function

Nice job on the new Linux Gazette! I'm just scanning it and had a few notes I thought I'd pass to you.

In the mail, there are a couple of things. Jim Murphy says that the "-print" option to find is necessary to get output from the find command and follows that up with "get used to it, its *nix". Well, he's part right. Linux does require this. However, any users who work on other Unix boxes will find slight differences in some of the common CLI commands (CLI is "command line interface"). For example, "find" on Solaris does not require the -print option to get output. Just food for thought.

Second, I have an xterm title bar function that people might find useful. I'll give the code first, then explain what it does:

In your .bashrc (or .kshrc - note this only works on ksh style shells) add the following:

    HOSTNAME=`uname -n`
    if [ "$TERM" = "xterm" ] && [ "$0" = "-bash" ]
    then
       ilabel () { echo -n "^[]1;$*^G"; }
       label () { echo -n "^[]2;$*^G"; }
       alias stripe='label $HOSTNAME - ${PWD#$HOME/}'
       alias stripe2='label $HOSTNAME - vi $*'
       cds () { "cd" $*; eval stripe; }
       vis () { eval stripe2; "vi" $*; eval stripe;}
       alias cd=cds
       alias vi=vis
       eval stripe
       eval ilabel "$HOSTNAME"
    fi

This does three things (as long as you're in an xterm and running bash):

1. when the xterm is first opened, the name of the current host is displayed in the title bar.
2. when you cd to a directory, the current path is displayed in the xterm title bar with the users $HOME directory stripped off the front end of the path (to save some space when you're somewhere in your own directory tree). The path is preceded by the current hosts network name.
3. when you use vi to edit a file the name of the file is displayed in the title bar along with the current hosts name. When you exit your vi session, the title bar reverts to the "hostname - path" format described in #2 above.

I found this very useful for all my ksh based systems because it removed the path from my shell prompt, thus saving me space for prompt commands. Since bash is a ksh compatible shell, this works quite well on standard Linux systems.

Hope everyone finds this useful.

    --
    Michael J. Hammel           |
    mjhammel@emass.com          | Consciousness: that annoying time between naps.
    mjhammel@csn.net            |
    http://www.csn.net/~mjhammel|

### More on Commenting Code in vi

Date: Mon, 09 Sep 1996 22:23:25 -0400
From: Jeff Blaine <jblaine@nda.com>
Subject: $0.02 tip - More on commenting code in vi

I'm generally ON the code I want to comment, so instead of having to find out line numbers and then perform a substitution on those lines to insert # characters, I just map my # key to "go to the beginning of the current line, go into insert mode, insert a # and a space, exit insert mode, go down one line"

You can map your # key this way (or whatever key you want to assign it to, but be careful) by putting the following in your .exrc file:

    map # I# ^[j

That "^[" is created by typing Ctrl-v and then hitting ESC, so you literally type:

    map<SPACE>#<SPACE>I#<SPACE><Ctrl-v><ESC>j

Then all you have to do to go comment-crazy is find where you want to start and hold down your # key.

Jeff Blaine

### More X Term Title Trick 2

Date: Sun, 08 Sep 1996 23:38:31 -0500
From: the Edward Blevins <thedward@mail.utexas.edu>
Subject: Re:XTerm Title Trick 2

In issue #9 of LG, one of the two cent tips is about how to put the hostname in the title of your xterm. It mentions precmd for csh, but not the bash equivalent. The way I do this in bash is as follows:

      if [ $TERM = 'xterm' ]
      then export PROMPT_COMMAND='echo -ne
    "\033]2;"`whoami`@`hostname`"\007"'
      fi

this can just go in your .bashrc, lots of fun. I add the whoami, because I am a sysadmin, and its a convienient way to tell if I am root, in addition to the '#' on the prompt. Another variation I use sometimes is : "`whoami`@`hostname`:`pwd`" then I can remove the path from my prompt.

ps the LG is GREAT! Keep up the good work. Thank you very much!

    --
    the Edward Blevins
    thedward@mail.utexas.edu

### Bash Quick Tip

Date: Thu, 12 Sep 1996 14:59:41 +1000
From: Jeremy Laidman <JPLaidman@ACSLink.net.au>
Subject: Bash Quick tip

Issue 8 had a 2c tip "There and Back!" describing a neat way to change between two directories quickly. The method was to use "cd ~-" which will set the working directory to the previous one you were in.

Bash (and several other shells I've tested) will do this without the tilde, ie "cd -". This saves me two keystrokes (including the shift key).

Cheers

    ----------------------------------------------------------------
    Jeremy Laidman                          JPLaidman@ACSLink.net.au
    Networking Consultant                            +61 0416 290866
    Canberra Institute of Technology                  +61 6 207 4272

### Neat Red Hat Management Trick

Date: Mon, 16 Sep 1996 01:33:51 -0400 (EDT)
From: Mike Acar <mike@contract.kent.edu>
Subject: Neat Red Hat management trick

Well, it's not really a trick per se. If you're like me, you make an attempt to keep your Red Hat system current- at least, in some respects. Tonight, looking at a man page which mentioned Linux 0.99.11 brought to mind the thought that I should upgrade my aging Red Hat 2.0 installation to something more current; fast on its heels was a curiousity about just what I have taken from where. So with a little bit of shell-play and some suggestions from my friend, the following was produced:

    rpm -qai | grep Dist | awk -F': ' '{print $3}' | sort | uniq -c

This will tell you all the distributions you have installed RPMs from, and the number of RPMs from each.

Mike Acar, mike@contract.kent.edu
Bret Martin, bret.martin@yale.edu

    --
    DZ-015 (Mike Acar)         Information Retrieval        Ministry of Information

### More on Find and Alternatives

Date: Sat, 14 Sep 1996 19:50:55 -0400 (EDT)
From: Bill Duncan <bduncan@beachnet.org>
Subject: find tip...

Hi Jim Murphy.
Saw your "find" tip in issue #9, and thought you might like a quicker method. I don't know about other distributions, but Slackware and Redhat come with the GNU versions of locate(1) and updatedb(1) which use an index to find the files you want. The updatedb(1) program should be run once a night from the crontab facility. To ignore certain sub-directories (like your /cdrom) use the following syntax for the crontab file:

    41 5 * * *  updatedb --prunepaths="/tmp /var /proc /cdrom" > /dev/null 2>&1

This would run every morning at 5:41am, and update the database with filenames from everywhere but the subdirectories (and those below) the ones listed.

To locate a file, just type "locate filename". The filename can also do partial matching. The search only takes a few seconds typically, and I have tens of thousands of files.

The locate(1) command also has regular expression matching, but I often just pipe it through agrep(1) (a faster grep) to narrow the search if I want. Thus:

      locate locate | agrep -v man

..would exclude the manpage for example, and only show me the binary and perhaps the sources if I had them online. (The -v flag excludes the pattern used as an argument.) Or the binary alone along with a complete directory listing of it with the following command:

      ls -l `locate locate | agrep bin`

The find(1) command is a great "swiss-army knife" (and actually not that bad once you get used to it), but for the 90% of the cases where you just want to search by filename, the locate(1) command is *far* faster, and much easier to use.

    --
    Bill Duncan, VE3IED  | BeachNet  -->  http://www.beachnet.org
    bduncan@BeachNet.org |   - Network/System Administration
    bduncan@ve3ied.uucp  |   - Web Design, Hosting Services
    +1 416 693-5960      |   - System Analysis/Design/Programming

### Pico Control M Trick

Date: Sat, 14 Sep 96 09:28 PDT
From: Peter <pb@europa.com>
Subject: Easier ^M removal with Pico

I've been using this trick for a long time .. its a lot easier then defining macros in Emacs, too. All it requires is a recent copy of the Pico editor.

Load the file you wish to strip ^Ms from, make a small change in the file (like hitting the space bar, then delete), and save it. No more ^Ms!

Peter

### Yet Another Emacs Control M Trick

Date: Tue, 24 Sep 1996 19:26:10 -0700
From: Dan Gunter <dang@hooked.net>
Subject: re: emacs ^M trick

I'm new to emacs, so I use a very simple trick to search & replace on special characters: I cut or copy them into the paste buffer, then Meta-% and hit Control-Y to yank them back into the minibuffer. This isn't elegant, but it's very easy to remember, and seems to work for everything.

This page written and maintained by the Editor of Linux Gazette, gazette@ssc.com