shell script

Discussion in 'Mac Programming' started by jamesapp, May 31, 2008.

  1. jamesapp macrumors 6502a

    Joined:
    Mar 7, 2008
    #1
    got the following script from a unix website:

    Code:
    #! /usr/bin/ksh
    #
    #  scroller ---  display text, but sleep every few lines.
    #
    #
    #  scroller will copy 5 lines from standard input to the 
    #  local terminal and then sleep for one second.  
    #
    #  You  can override the 5 lines with a "-l n" option.  
    #  And you use  a "-s n" to override the sleep time.
    #
    #  You can type your interrupt character (often control c)
    #  to get a menu that will let you adjust these values.
    #
    #  You can use -m to go straight to the menu at startup
    #  
    #  You can specify filenames or scroller can just read from 
    #  standard in.
    #
    USAGE="usage: scroller [-s n] [-l n] [-m] [filename1] [filename2] ..."
      
    #
    #  initialize variables
    #
    #  Set reasonable initial values here.  TASK controls the main 
    #  loop as described below.  snooze is the number of seconds for
    #  the sleep.  lpp (lines per page) is the number of lines to
    #  dispaly before sleeping.  lines will repeatedly cycle from 0
    #  to npp as the program runs.  totallines is a count of lines
    #  processed so far.  And we turn off IFS so the reads work with
    #  data that has leading white space.
      
    TASK=2
    snooze=1
    lpp=5
    lines=0
    totallines=0
    IFS=""
    
    #
    #  Now Process the command line
    #
    
    error=0
    while getopts :s:l:m  o ; do
            case $o in
            s)      if [[ $OPTARG -gt 0 && $OPTARG -lt 100 ]] ; then
                            snooze=$OPTARG
                    else
                            print $OPTARG is illegal
                            error=1
                    fi
                    ;;
            l)      if [[ $OPTARG -gt 0 && $OPTARG -lt 100 ]] ; then
                            lpp=$OPTARG
                    else
                            print $OPTARG is illegal
                            error=1
                    fi
                    ;;
            m)      TASK=2
                    ;;
            ?)      print error argument $OPTARG is illegal
                    error=1
                    ;;
            esac
    done
    shift OPTIND-1
    if ((error)) ; then
            print $USAGE
            TASK=0
    fi
    
    
    #
    #  Open first file or indicate that we are using stdin
    #
    
    if (($# >= 1)) ; then
            input=$1
            exec < $input
            shift
    else
            input="(standard input)"
    fi
    
    
    #
    #  Major loop.  TASK can be 0 or 1 or 2.  If TASK is set we 
    #  loop doing either task 1 or task 2.  Either task can switch 
    #  to the other.  And both tasks can abort by setting TASK=0.  
    #  But control c will switch to task 1.
    #
    
    trap interrupt=1 2
    interrupt=0
    while ((TASK)) ; do
            if ((interrupt)) ; then
                    interrupt=0
                    TASK=1
            fi
            case $TASK in
    
    #
    #   Task 1 --- display service menu
    #
    
            1)      print  
                    print  '=====[[ scroller service menu ]]====='
                    print
                    print  "      $totallines lines processed so far from $input"
                    print  "      sleep seconds = $snooze"
                    print  "      lines per page = $lpp"
                    print  
                    print  '   1) list the text'
                    print  '   2) set lines per page'
                    print  '   3) set sleep seconds'
                    print  '   4) abort'
                    print
                    print -n  "[Enter Selection]====>>"
                    read < /dev/tty
                    case $REPLY in 
                    1)      TASK=2
                            ;;
                    2)      print lines per page is currently $lpp
                            print -n enter new value --
                            read val < /dev/tty
                            if [[ $val -gt 0 && $val -lt 100 ]] ; then
                                    lpp=$val
                            else
                                    print $val is illegal
                            fi
                            ;;
                    3)      print sleep seconds is currently $snooze
                            print -n  enter new value --
                            read val < /dev/tty
                            if [[ $val -gt 0 && $val -lt 100 ]] ; then
                                    snooze=$val
                            else
                                    print $val is illegal
                            fi
                            ;;
                    4)      TASK=0
                            ;;
                    *)      print illegal response
                            print REPLY = $REPLY
                            ;;
                    esac
                    ;;
    
    #
    #  Task 2 --- copy lines from stdin to stdout
    #
    #    Read a line, increment counts, sleep if it's time
    #
    
            2)      if read line ; then
                            print -r -- "$line"
                            ((totallines=totallines+1))
                            ((lines=lines+1))
                            if ((lines >= lpp)) ; then
                                    lines=0
                                    sleep $snooze
                            fi
                    else
    #
    #    No more input.  Open a new file or give up.
    #
    
                            if [[ $# -ge 1 ]] ; then
                                    input=$1
                                    exec < $input
                                    shift
                            else
                                    TASK=0
                            fi
                    fi
                    ;;
    
    #
    #   Task * --- can't happen
    #
            *)      print -u2 $0: impossible error TASK = $TASK
                    TASK=0
                    ;;
            esac
    done
    
    ((totallines)) && print "$totallines" total lines processed
    
    exit 0
    
    how do i run this script?
    can i change the beginning line to:

    Code:
    #! /usr/bin/ksh
    
    to:
    Code:
    #!/usr/bin/bash
    
    how do i run this script?
     
  2. tyr2 macrumors 6502a

    tyr2

    Joined:
    May 6, 2006
    Location:
    Leeds, UK
    #2
    Change the first line to

    #!/bin/ksh

    And it should run just fine.
     
  3. yeroen macrumors 6502a

    yeroen

    Joined:
    Mar 8, 2007
    Location:
    Cambridge, MA
    #3
    ksh, the Korn shell, is installed on OS X/Darwin. You don't need to switch to bash (in fact doing so may even break the script).

    To run the script, type either:

    ./scriptname

    or

    source scriptname

    in the terminal.
     
  4. dvince2 macrumors 6502

    dvince2

    Joined:
    Mar 6, 2007
    Location:
    Canada
    #4
    Code:
    #! /usr/bin/ksh
    
    Anything behind a # is commenting, so this is just telling the user what shell they should be in to use it. To use it, you have to change the permissions to be executable:
    Code:
    chmod u+x FILENAME
    
    where FILENAME is the name of the script.
    to execute it, just type the name.
     
  5. tyr2 macrumors 6502a

    tyr2

    Joined:
    May 6, 2006
    Location:
    Leeds, UK
    #5
    Actually no, the first line with '#!' (the hash bang) tells the OS which executable to use to execute it. It is not a comment. For example perl scripts start "#!/usr/bin/perl".
     
  6. litesgod macrumors newbie

    Joined:
    Apr 3, 2008
    #6
    In a script, the #! line is not a comment, it happens to be the ASCII equivalent of a magic number telling the machine how to execute the file. On OS X, the line should probably read
    Code:
    #!/bin/ksh

    dvince2 is correct- the file needs to be set as executable prior to you running it. After that, everything should work fine.

    If you don't want to modify the file, you could execute using ksh explicitly by entering
    Code:
    ksh FILENAME
    in the terminal.
     
  7. jamesapp thread starter macrumors 6502a

    Joined:
    Mar 7, 2008
    #7
    tried:
    Code:
    ksh FILENAME
    
    script worked

    one thing i would mention is that the script is meant to be a text scrolling script. my cursor in terminal stayed on the bottom left hand side of the screen. i have an older computer running ms-dos, and it scrolls text. like the cursor moves from left to right across the screen fairly rapidly and is replaced by text. this script is close to what i want. from the same website i got a c program which is as follows
    source file nodoff.c:

    Code:
    #ifdef __STDC__
    #define PROTOTYPICAL
    #endif
    #ifdef __cplusplus
    #define PROTOTYPICAL
    #endif
    
    #include <stdlib.h>
    #include <sys/time.h>
    
    #ifdef PROTOTYPICAL
    int main(int argc, char *argv[])
    #else
    main(argc,argv)
    char *argv[];
    #endif
    
    {
            int millisecs, microsecs;
            struct timeval tv;
    
            millisecs=atoi(argv[1]);
            microsecs=millisecs*1000;
    
            tv.tv_sec=microsecs/1000000;
            tv.tv_usec=microsecs%1000000;
    
            select(0, NULL, NULL, NULL, &tv);
            exit(0);
    }
    
    when i compiled this source program it compiled without any errors.
    but when i went to run it using the command line:

    Code:
    ./nodoff 500 filename
    
    where file name is a file in my current working directory.
    When i ran the program nothing seemed to happen.
    on the unix website the person who wrote the c program switched from a shell script to c because he wanted to put the computer to sleep for less than a second.
    and he said that would be
    "Sleeping for less than a second is not a real good idea in a script. The overhead required to launch a process is too great. The right thing would be to switch to c. But it is easy to write a program like sleep that will sleep for less than a second if you want to give it a try. I wrote one that I call "nodoff". It sleeps for milliseconds. So "nodoff 500" is a half a second. Here it is..."
    and the above c program was what he came up with. I am just wondering what i am doing wrong?
     
  8. jamesapp thread starter macrumors 6502a

    Joined:
    Mar 7, 2008
    #8
    i want to edit the previous post.
    in terminal i used the command line:

    Code:
    ./nodoff.out 500 filename
    
    where filename is a file in my current working directory.
    and nothing happened.
     

Share This Page