Cannot get this bash/expect script to run under a crontab

#!/bin/bash
# 
# RAP configuration script
#
# Usage: ./rap.sh
#
# Requires: expect, tcl
#
# Script expects to find a file called rap.csv located in the same directory as the script. If the file is placed
# in a different directory, modify the custom entries section to specify the absolute path to the rap.csv file.
#
# rap.csv should be in this format:
# MAC address,AP-group,AP-name,Description
# 00:00:00:00:00:00,East-VIP,JunaidTest,TestRAP2
#
# Controller command format:
# local-userdb-ap add mac-address 00:00:00:00:00:00 ap-group East-VIP ap-name JunaidTest description TestRAP2 full-name rap-user
#
# Caveats:
#
# - A failure to execute a command on the controller is not gracefully handled and the output file shows that the entry
# has been processed when it may not have been.
# "Invalid input detected at '^' marker."
# "Userwith same remote IP already exists"
# - Login failures are not gracefully handled:
# bad username/password 
# inability to connect to controller
# ssh_exchange_identification: Connection closed by remote host
# - Failure to enter enable mode on controller is not gracefully handled.
# - Script will "hang" if server on which the script is hosted has never accessed the controller (No server SSH key stored locally)
# Are you sure you want to continue connecting (yes/no)? yes 
# Warning: Permanently added '10.37.192.160' (RSA) to the list of known hosts. 
# (Workaround: connect once to controller from the server hosting the script and manually say "yes" so that the host is saved.)
#
# Customize this block as needed
# BEGIN custom entries
echo "This is running"
export PROG="/ftp/office_in_a_box/rap.sh"
export RAPCSV="/ftp/office_in_a_box/rap.csv"
export USER=test
export PROMPT=".*\]\$ "
export PROMPT1=".*\) >"
export PROMPT2=".* #"
export PASSWORD1="password"
export PASSWORD2="password"
export HOST="10.10.10.10."
# END custom entries
#
#
# Set common 
export PATH="/usr/local/bin:/usr/bin:/usr/sbin:/bin:/sbin"
DATE=`date +%Y-%m-%d-%H%M%S`
OUTFILE=$RAPCSV.out.$DATE
#
print_usage() {
echo "Usage: $PROG"
}

while test -n "$1"
do
print_usage; exit $STATE_UNKNOWN
done

while IFS= read -r line; do
MAC=`echo $line | awk -F, '{ print $1 }'`
APGROUP=`echo $line | awk -F, '{ print $2 }'`
APNAME=`echo $line | awk -F, '{ print $3 }'`
DESC=`echo $line | awk -F, '{ print $4 }'`
ADDED=`echo $line | awk -F, '{ print $5 }'`
MACCHECK=`echo $MAC | sed -n "/^\([0-9A-Fa-f][0-9A-Fa-f]:\)\{5\}[0-9A-Fa-f][0-9A-Fa-f]$/p"`
SKIP=0
# Check to see if entry has been processed, has the right fields and if the MAC is formatted properly.
# If any check fails, the entry will be skipped and a notation written to the output file.
if [[ -n $ADDED ]]; then
echo "Entry already processed. Skipping $line." >> $OUTFILE
SKIP=1
elif [[ -z $DESC ]] && [[ $SKIP == 0 ]]; then
echo "Entry must have a Description. Skipping $line." >> $OUTFILE
SKIP=1
elif [[ -z $APNAME ]] && [[ $SKIP == 0 ]]; then
echo "Entry must have an AP Name. Skipping $line." >> $OUTFILE
SKIP=1
elif [[ -z $APGROUP ]] && [[ $SKIP == 0 ]]; then
echo "Entry must have an AP Group. Skipping $line." >> $OUTFILE
SKIP=1
elif [[ -z $MAC ]] && [[ $SKIP == 0 ]]; then
echo "Entry must have a MAC Address. Skipping $line." >> $OUTFILE
SKIP=1
elif [ -z $MACCHECK ] && [ $SKIP == 0 ]; then
echo "Incorrect format for MAC Address. Skipping $line." >> $OUTFILE
SKIP=1
fi
# If no conditions set SKIP=1, then set variable cmd to equal the command to send to the controller.
if [ $SKIP == 0 ]; then
cmd=`echo "local-userdb-ap add mac " $MAC " ap-group " $APGROUP " ap-name " $APNAME " description " $DESC " full-name rap-user "`
# Initiate expect session
# Uncomment EXEC=$(expect -d -c " line and comment out EXEC=$(expect -c " line to enable debug output to screen."
# EXEC=$(expect -d -c "

EXEC=$(expect -c "
unset -nocomplain ::env(SSH_AUTH_SOCK);
stty echo 
set timeout 60
spawn ssh -o StrictHostKeyChecking=no $USER@$HOST
# Look for password prompt and send login password
expect \"*?assword:\"
send -- \"$PASSWORD1\\r\"
send -- \"\\r\"
# Look for prompt that indicates that we have successfully logged in
expect \"$PROMPT1\"
send -- \"en\\r\"
# Look for enable password prompt and send enable password
expect \"*?assword:\"
send -- \"$PASSWORD2\\r\"
send -- \"\\r\"

# Look for prompt with "#" indicating that we have successfully entered enable mode and send command to add entry
expect -re \"$PROMPT2\"
send -- \"$cmd\\r\"
send -- \"\\r\"
# Look for prompt with "#" indicating that the controller has returned to the prompt after executing the command and
# send command to save the configuration.
expect -re \"$PROMPT2\"
send -- \"write mem\\r\"
# Look for prompt with "#" indicating that the controller has returned to the prompt after executing the command and
# send logout command
expect -re \"$PROMPT2\"
send -- \"exit\\r\"
")
# Write to the output file that the entry has been processed 
echo "Processed $line." >> $OUTFILE
# Process the entry line to escape any special characters and then update rap.csv by appending ",ADDED" to the entry.
safe_line=$(printf "%s\n" "$line" | sed 's/[][\.*^$(){}?+|/]/\\&/g')
safe_replace=$(printf "%s\n" "$line" | sed 's/[\&/]/\\&/g; s/$$/\\&/; s/^^/\\&/; s/[0-9].*/&\,ADDED/')
sed -i "s/${safe_line}/${safe_replace}/" $RAPCSV
fi
done < $RAPCSV
exit 0

Please post what Operating System and version you are running, the line from crontab, any error messages found in the unix mail for the owner of the crontab, and any evidence you have of the failure which might give folks a clue what to look for.

First impression is that running an interactive process which requires a terminal is not going to work when there is not a terminal context (i.e. in cron). The error messages should support this.

1 Like

as half the portion of the script is bash there are no errors. The cron job is running under a normal user as i am not the admin of the box. The script by itself works just fine.

it is

Red Hat Enterprise Linux ES release 4 (Nahant Update 6)
*/5 * * * * /ftp/office_in_a_box/rap.sh

Whats your OS?

is your user in cron.allow?

cat /var/adm/cron/cron.allow

---------- Post updated at 03:54 PM ---------- Previous update was at 03:53 PM ----------

Also can you post the output of the error?

1 Like

Imho. There should be error messages in the unix server mail for the owner of the cron.

Anyway, this process looks like it should be using a Remote Shell not an Interactive Shell.

Though the script is particularly difficult to follow, it seems to just execute a write mem command on the remote system, store the results to a file and then parse the results.

1 Like

thanks guys but i found my stupid mistake it was the stty statement in the expect script :frowning:

1 Like

For the benfit of those following this thread, where did you find the error message "not a terminal" or whatever?

1 Like

put this statement in the crontab

*/5 * * * * /ftp/office_in_a_box/rap.sh 2>/tmp/rap.err 1>/tmp/rap.out
 
got this result

[bluecoat_ftp@bb-va01-sv55-nm office_in_a_box]$ cat /tmp/rap.err 
stty: impossible in this context
are you disconnected or in a batch, at, or cron script?stty: ioctl(user): bad file number
    while executing
"stty echo "
stty: impossible in this context
are you disconnected or in a batch, at, or cron script?stty: ioctl(user): bad file number
    while executing
"stty echo "
stty: impossible in this context
are you disconnected or in a batch, at, or cron script?stty: ioctl(user): bad file number
    while executing
"stty echo "
stty: impossible in this context
are you disconnected or in a batch, at, or cron script?stty: ioctl(user): bad file number
    while executing
"stty echo "
1 Like

Thank you for responding. We all learn more when things do not go to plan.

Wow. That's the most obscure version of "not a terminal" I have ever seen .... unless someone has seen a better one.

Anybody Googling that error message will find this thread. That is good.