Cron – expect script running screen stops working when run by cron

cronexpectgnu-screenserial

I hope this question is OK for this forum.

I have a device, a modem. I talk to this modem with the linux program "screen" as a terminal program. I invoke it like this "/usr/bin/screen /dev/tty6". I need to send about 6 commands per session or so. I use an expect script so I can automate the process. The expect script spawns the screen process, sends the commands then exits.

This system works fine when I run it from a terminal session or when I run it remotely using ssh from another machine. But when I use cron to run it, it fails. On the local machine it fails with an error like: spawn id exp6 not open while executing exp_send. It does that on the third send in the expect script.

I tried to use cron to run remotely using ssh with the -t, -tt, -ttt options but I get the error: "Pseudo-terminal will not be allocated because stdin is not a terminal."

My crontabs have a path variable set, nevertheless most of the commands are invoked with a full path, I'm pretty sure.

I tried spawning screen with a -m option but it still fails apparently to spawn. Spawning screen and detaching it doesn't make any sense in this scenario. Part of the issue seems to be that running screen as a terminal emulator to a serial port is different to running it normally. Any help or insight would be greatly appreciated.

The expect script here:

—do-stuff.exp

#!/usr/bin/expect -b

set verbose 0
set verb [lindex $argv 0]
if { $verb eq "-v" } {
  set ::argv [lassign $::argv verbose]
  set verbose 1
}

set phone [lindex $argv 0]
set message [lindex $argv 1]

if { $verbose == 1 } {
  send_user "phone = ($phone)\n"
  send_user "message = ($message)\n"
}

set force_conservative 1  ;# set to 1 to force conservative mode even if
if {$force_conservative} {
    set send_slow {1 .1}
    proc send {ignore arg} {
        sleep .1
        exp_send -s -- $arg
    }
}

# turn off screen echo
if { $verbose == 0 } {
  log_user 0
}

set timeout -1
spawn /usr/bin/screen /dev/tty6 cs8
match_max 100000

# wait 100 milliseconds
after 100
send -- "+++"
after 100
send -- "ATZ\r"
expect -exact "OK\r
" 
send -- "AT+CMGF=1\r"
expect -exact "OK\r
"
send -- "AT+CMGS=\"$phone\"\r"
expect -exact "
> "
send -- "$message\r"
expect -exact "\r
> "
send -- "^Z"
expect -exact "OK\r
"
send -- "^Ak"
after 500
send -- "y"
#expect eof
exit 0

——–the cron tab

/etc/cron.d/local-test

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
# m h dom mon dow user command
*/3 * * * 1-5  fred        /home/fred/do-stuff.exp -- -v 12345678 "test message cron 2"

The cron email

phone = (123456789)
message = (test message cron 2)
spawn /usr/bin/screen /dev/tty6 cs8
Please set a terminal type.
+++ATZ
send: spawn id exp6 not open
   while executing
"exp_send -s -- $arg"
   (procedure "send" line 3)
   invoked from within
"send -- "AT+CMGF=1\r""

Best Answer

It looks like I just have to add:

TERM=vt100

to my cronfile. Ouch.

All working now.