Link to home
Start Free TrialLog in
Avatar of Cherylvan
Cherylvan

asked on

I need to write a unix shell script to run with cu

I have some machines that I have to dial into but it will be done automatically passing the password without any user interaction.  I know how to cu to a machine cu -s(baud rate) phone-number | tee out_file but I don't know how to get the parameters passed and was told I need to write a shell script to do this.  I am terrible at writing shells.  What I'm needing to do is:
I'll run the cu -s1200 tel_num | tee out_file
The machine will then display connected and I will need to send it a \n (newline).
The other machine will expect a password and I will need to send it one (this password will be coming from a file).
I will then send it a command once logged in called test for example which will run a program and generate a file which will go to the out_file in the first command.
When this is thru, I will want to send it a bye\n (bye and newline) and then ~.\n to logout.

Any help will be greatly appreciated.

thanks,
Cheryl
Avatar of Tintin
Tintin

Does your version of cu have the -C flag to run a command?

If not, then writing an expect script is going to be your best bet.
Agreed with Tintin, try to use expect script.

Information/download expect :
http://expect.nist.gov/

after install expect, you can use "autoexpect" to create an expect
script and them modify the script.

man autoexpect
to learn more details

Also have a look at the following expect script examples:
http://floppsie.comp.glam.ac.uk/Glamorgan/gaius/scripting/5.html

In case you need more help, please post the sample expect script created by autoexpect.
(becaue the "expect" messages are system depandent !)

If we know your OS version, you migh be able to download the exect binary packages.
(make sure that you install tcl, tk and libgcc as well)  eg:

for Solaris get it from:
http://sunfreeware.com/

for HP-UX:
http://hpux.cs.utah.edu/hppd/hpux/Tcl/expect-5.42/

Avatar of Cherylvan

ASKER

We do have -C for a script.  The problem is, I don't know how to write the script to get all this information into the dialing string.  We don't have "expect" and there is no chance of us getting it on the machine.  We have to go thru a whole variance process which takes almost a year and then ultimately ends up getting rejected :( I don't have to work with shell scripting very much so my knowledge of it is very very small.  Please help!!!

Cheryl
Ah, the joys of locked-down QA...

Does your machine have bourne shell?  (/bin/sh)
Does it have bourne-again shell (bash)?
Can your machine support named pipes?

Does your machine have a C compiler of any sort on it?
Come to think of it, what type of computer is it, and what's it running?
It might be that, given that you have implicit permission to put any user-changes you like on the machine in pursuit of this particular issue, having your own private copy of the "expect" binary would not be a "configuration change" (it wouldn't be installing it into /bin after all), it would merely be part of your software feature.
The "expect" tool really was designed exactly for this sort of thing.  It is possible to do similar things with shell scripts and pipes, but it's rather awful in comparison.

You create a couple of named pipes.
You run your cu command, redirecting output to one named pipe I'll call "fred", and redirecting input from the other that I'll call "wilma".
You then run your script, redirecting output to the named pipe "wilma" and input from the pipe called "fred"
Your script (assuming it's bourne-shell or bash) will read from what it considers to be stdin using the "read" command, e.g.
  read LINE
reads a whole line, up to the next LF, and puts the result into the variable LINE
and it outputs to what it considers stdout using the "echo" command, e.g.
  echo "bye"
  echo "~."

The main difference between using "sh" or "bash", and using "expect", is the level of robustness that's easy to write.
With "expect", it's possible to have timeouts and deal with things not working as planned.  with the shell script version, it'll either work, fail or hang - much more difficult to make it deal with retries & any other awkwardness.
Fortunately even modem links tend to have error-correction on them these days, so you either get correct data or nothing.

See if you can find a binary of "expect" for your machine that you can dump in the same directory you're intending to put your scripts in.  If anyone from your QA dept whinges, just point out that it's no more a risk than bespoke scripts (and far more efficient!).
Peter,

I am working on a mid-range sun solaris that does have bourne shell.  I have checked all over for any type of 'expect' but it just isn't there.  I'm pretty sure it will support named pipes.  I am a software developer and the only was I can get stuff installed on the machine is thru a CSA and they make us fill out a change management work order and there is no way this will fly because it is not a standard install on this machine.  Why? I have no idea.  Having anything installed or changed on this machine without approval is a 'fireable offense' so we have to find really creative ways around things that should/could be done easily.  If you can help me, even if its doing it in an ugly script, I would really appreciate it.  I'm getting desperate :(

Cheryl
Hi Cheryl,

    Since you are running Solaris, you can download the expect binary package from
http://sunfreeware.com/

    Please read the readme file and download and install all the depandeces package.
    see: http#12601748

    Then just run "autoexpect" to create an expect script, if you need more help for modifing the expect script. We can help you out.

 >>   "solaris that does have bourne shell",

    are you sure? please try in the following commands to verify:

   ls -al /sbin/sh
   ls -al /usr/bin/sh

   sh should be installed in any case, your System startup scrip use them!
Cherylvan,

I think we need a little more detail on your 'fireable offense' constraints.
I've worked under such conditions before, and I've found that whilst those in charge of enforcing such issues are almost universally ignorant and unable to do a proper risk assessment, it's often possible to find a way around such contraints.

Firstly, do you have permission to make any software changes to the machine that will be doing the dialing-out?
Secondly, what about the ones you're dialing into?

If the answer is "no" to the first question, then that rather implies that you're not authorised to work on this issue at all, and begs the question of why you're investigating something that you're not allowed to do ("corporate politics" being the common reason ;-)

If the answer is "yes" to either, we then have to determine what is deemed an acceptable software change.
It sounds like anything that adds things to the standard /bin (and so on) areas is out of the question, but what about putting additional files elsewhere?
After all, if you're not allowed to put any files anywhere on the box (and modifying existing files would endanger existing functionality) then you're not allowed to do this at all, hence end of enquiry.

So you must, therefore, be permitted to make some changes to one or more areas on the machine in pursuit of this particular goal, otherwise you wouldn't have started asking.

If you have an area on a filesystem somewhere in which you are allowed to place data files and executable files, then "expect" is not ruled out - it's just an executable, it doesn't need root permissions to run or anything special, and hence is just as much a security/functionality risk as any shell script.

However, if you're dead-set on the shell-script option, it's possible.
You're a software developer, hence you've probably heard of the ETLA "RTFM" ;-)   Unix has a good FM, and "man sh" is actually a good reference, once you've learned the basics.
The basics are:
Start your shell script file with the lines
  #!/bin/sh
  #
  # write some comments here to say what your script does
  #
(although don't put in the two spaces at the start of each line - I put them there just to mark the start & end of what I was quoting)
You can define a function by stating
  my_function_name()
  {
  }
Arguments will be passed into the function as ${1}, ${2} etc (or ${*} means "all arguments seperated by spaces")
Stdin, stdout and stderr will be whatever was set up when the function was called.
You call a function as if it were another unix command in its own right, and don't include the (), e.g.
  my_function_name firstArgument secondArgument
A function can return a number using the "return" keyword.  Zero is "true" and non-zero is "false" when using if statements.  e.g.
  if my_function_name argumentOne argumentTwo
  then
    echo "my function said it worked"
  else
    echo "my function said it failed and returned ${?}"
  fi
Variables can be set just by saying
  VARIABLE=value
but it's important to note that all variables are global, except arguments.

So, you could have a script which went something like

#!/bin/sh
#
# Arguments:
#   <file-for-test-output> <test command for far end> [ <argument for test command> ... ]
#

# reads from stdin, outputs to stdout.
wait_for_connected()
{
  # read in lines until one says "CONNECTED"
  WFC_LINE=""
  while [ "${WFC_LINE}" != "CONNECTED" ]
  do
    read WFC_LINE
  done
  # now send out a LF
  echo ""
}

# $1 is the password
# outputs to stdout
send_password()
{
  # wait a moment for the other end to be ready to accept the password
  sleep 1
  # now send it
  echo "$1"
}

# $* is the command to run, with arguments
# outputs the command to stdout
send_command()
{
  # wait a moment before sending the command
  sleep 1
  echo $*
}

# stdin is the output from the command
# stdout is where the results do
receive_results()
{
  # now read in all the lines from the other end and spit them to stdout, but
  # don't spit out the final "bye" and "~." lines that we sent.
  RRAL_LINE1=""
  RRAL_LINE2=""
  while [ "${RRAL_LINE1}" != "bye" -a "${RRAL_LINE2}" != "~." ]
  do
    read RRAL_LINE
    echo "${RRAL_LINE2}"
    RRAL_LINE2="${RRAL_LINE1}"
    RRAL_LINE1="${RRAL_LINE}"
  done
}

OUTPUT_FILE=$1
shift
wait_for_connected
send_password `cat my_password_file`
send_command $*
echo "bye"
echo "~."
receive_results_and_logout > ${OUTPUT_FILE}


Then you run that script telling it to get its input from one named pipe and send its output to the other named pipe (see my earlier comment for why), giving it the name of a file to spit the results to and the command it should run.  Oh, and it'll read "my_password_file" and expect that to contain the password and only the password.
That should be enough to get you started...
Peter-Darton,

I have permission to make software changes (of course I had to file a change management work order and have the client VP who doesn't know and doesn't care approve it).  I can make software changes, I just can't load/unload anything from the machine.  The CSA does that.  Your suggestion will work and I appreciate your helping me with this.

Have a good weekend and Thanksgiving.

Cheryl
ASKER CERTIFIED SOLUTION
Avatar of Peter-Darton
Peter-Darton

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial