Link to home
Start Free TrialLog in
Avatar of buckethead34
buckethead34

asked on

Expect Scripts and Crontab

I have 7 expect scripts in the /etc/t5k_scripts directory. I would like to run these daily, but I can't figure out what strings I need to add to the crontab. Can anyone help? Thanks in advance.
Avatar of fosiul01
fosiul01
Flag of United Kingdom of Great Britain and Northern Ireland image

crontab -e   [ to edit ]


you can add like this

00 1 * * 1-5 /etc/t5k_script/scriptname  

so it will run

moday to friday 1 am

you can modify thse anytime

have a look this site about crontab

http://www.adminschoice.com/docs/crontab.htm
Avatar of buckethead34
buckethead34

ASKER

That doesn't seem to be working.
which one?

you need to set EDITOR

EDITOR=vi ; export EDITOR
how exactly you are doing ??

When I run the scripts manually, I cd /etc/t5k_scripts then to run the script I do ./script.exp and it works fine. I just need to know the entry to go into the crontab. I tried
01 17 * * * cd "/etc/t5k_scripts"; ./script.exp
But it gives me an error
Not a directory: cd
/bin/bash: ./script.exp: No such file or directory
No
it should be like this



01 17 * * *  /etc/t5k_scripts/script.exp



but there mightbe a problem ..

you need to set the binary path to execute for .exp file, you need to set the path to execute the binary

but try 01 17 * * *  /etc/t5k_scripts/script.exp

if it does nto work then will see next step

put these in a script, make the script executable then put the path to the script in the crontab

01 17 * * * /path/to/myscript
for crontab jobs

- set required env variables e.g. PATH
- refer to files, directories and commands with full path names
- redirect stdin , stdout and stderr to files
The 01 17 * * *  /etc/t5k_scripts/script.exp  is not working.
What was said about the binary path setting it to execute?
Thanks
when crontab jobs are run they do not know about env variables so they should be set. also the script file should have the execute perm to run
You'll have to help me out on how to do this please. Thanks
The script does have the executer permission.
can you show your expect script?

set timeout -1
spawn $env(SHELL)
match_max 100000
expect -exact "]0;root@tvtftp:/etc/t5k_scripts[?1034h\[root@tvtftp t5k_scripts\]# "
send -- "telnet 10.100.72.211\r"
expect -exact "telnet 10.100.72.211\r
Trying 10.100.72.211...\r\r
Connected to 10.100.72.211.\r\r
Escape character is '^\]'.\r\r
Login:"
send -- "username\r"
expect -exact "username\r
Password:"
send -- "password\r"
expect -exact "\r
Miltonvale# "
send -- "config\r"
expect -exact "config\r
Miltonvale(config)# "
send -- "set control db-backup\r"
expect -exact "set control db-backup\r
\r
 Set Control done\r
Miltonvale(config)# PCM DB Backup in progress. No ADD/SET/DELETE commands will be processed
\r\r\r
PCM DB Backup Success.
\r\r\r
"
send -- "\r"
expect -exact "\r
Miltonvale(config)# "
send -- "logo\r"
You fine name has .exp extenstion

like normaly we use script.sh , so the binary of this file in #!/bin/bash

to execute a php file the binary of php file is  #!/usr/local/bin/php

like that

.exp file has a path to exectue,

do you that path ??

i think you need to change

send -- "telnet 10.100.72.211\r"

to

send -- "/usr/bin/telnet 10.100.72.211\r"
The .exp script runs fine manually. I don't think that it is a problem with the script but rather cron running it.
did you see my last comment and the one talking about requirements to run crontab jobs?

what errors do you get from the crontab job? you may redirect output / errors to a file

01 17 * * *  /etc/t5k_scripts/script.exp  > /path/to/file 2>&1
waht omarfarid said,

redirect the crontab log to a file or check your mail for root, it wil give you where crontab is failing

also, you wil have to define the binary path by hand in the script also in the crontab if binary path is not set on your profie
Ok, so I've resorted to creating a run.sh script. I put all of the expect scripts in this to run. I have the run.sh script in the /usr/bin directory. My run.sh script looks like

cd /etc/t5k_scripts
./script1.exp
./script2.exp
./script3.exp
./script4.exp
./script5.exp
./script6.exp
./script7.exp

When I do crontab -l
I get
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/bin/expect
MAILTO=root
HOME=/

58 11 * * * /usr/bin/run.sh

Any ideas on why it is not running.

By the way when I type /usr/bin/run.sh it runs all the expect scripts and works just fine. Thanks in advance.
did you try to set env variables? it does not show that it did not run
ok 58 11 that meant, it will run at 11 am 58 minutes, it would not run before that.

to check it now, do it something every minutes

* * * * * /usr/bin/run.sh

so it will run following minutes

to see any error , look at

/var/log/crontab


or
* * * * * /usr/bin/run.sh > /path/to/crontablog 2>&1
check in crontab log, see what errro do you see
past those error here

Here's the log that I had redirected. No errors just nothing really at all.
more /etc/cronlog.txt
spawn /bin/bash
bash-3.2#
is your cron job executing ???

cd /var/log/
tail -f cron

it will show you if your cron is executing ...

let me know if it show that cron is executing ..
Yes they are running.
Apr 16 13:48:01 tvtftp CROND[2455]: (root) CMD (/usr/bin/run.sh > /etc/cronlog.txt 2>&1)
Apr 16 13:49:01 tvtftp CROND[2503]: (root) CMD (/usr/bin/run.sh > /etc/cronlog.txt 2>&1)
Apr 16 13:50:01 tvtftp CROND[2513]: (root) CMD (/usr/bin/run.sh > /etc/cronlog.txt 2>&1)

Ok we might be doing little bit of mistake

do this
use >> instead of >



* * * * * /usr/bin/run.sh >> /path/to/crontablog 2>>&1

now you sh ould see error in crontablog

also, are you dong this as root ??
[root@tvtftp ~]# more /etc/cronlog.txt
spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2#
Yes doing this as root.
you are gettign wired output ....
let me do some google ...
The very first line of your expect script should have

#!/usr/bin/expect

or whatever the path is to expect on your system.
That's true what Tintin is saying. When running from crontab, the system will not recognize the type of the script without the absolute path to the interpreter (/path/to/expect in your case)

You can try: man expect

Then go to usage and you should see more about the same thing.
I moved the run.sh file to /bin/ and I set the home folder to /root and now the cronlog changed after I made those adjustments. Looks like it is changing to the directory to run the expect scripts.

spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
bash-3.2# spawn /bin/bash
[root@tvtftp t5k_scripts]# spawn /bin/bash
[root@tvtftp t5k_scripts]# spawn /bin/bash
[root@tvtftp t5k_scripts]# spawn /bin/bash
[root@tvtftp t5k_scripts]#
The #!/usr/bin/expect is in there. The expect scripts run fine, my problem is getting the cron job to execute the run.sh script now, which contains the expect scripts. The run.sh command works. Is there a better way to run a command automatically at a certain time?
Expect scripts *do* work under cron, but I think the problem is match strings in your expect script.  because you are expecting *exact" strings, if the prompt, for example, varies only slightly from the one you want to match, you will never run the rest of the script.  cron jobs don't have a TERM  environment variable set, so the shell will probably not print the exact control sequence you specify.

I would suggest a few things:
- Make  the first line "#!/usr/local/bin/expect --" (the "--" at the end stops any script parameters being treated as parameters to the "expect" program)
- Remove the "spawn $env(SHELL)" and the first match string, and change the "send -- "telnet ..." to  "spawn telnet 10.100.72.21"
- Change your "exact" matches to match only the required string - for example, the first "expect" match after the "spawn telnet ...." could be         expect "ogin:"     (note the missing "L" from "Login:" - this allows it to match "login" or "Login" easily, in case the remote machine is altered slightly)
- If things still don't work, turn on debugging by adding the line:
    exp_internal 1
  to your script, to print out internal processing steps.
Ok, I've figured out what part of the problem was, the scripts would only run in a terminal window in the gnome environment. I've recreated the the scripts on a console window and now in the cronlog txt it gets stopped here.

spawn /bin/bash
[root@tvtftp t5k_scripts]# telnet 10.100.72.146
Trying 10.100.72.146...
Connected to 10.100.72.146.
Escape character is '^]'.
Login:username
Press (Q: quit, <cr>: line by line, S: no page, others: continue)Terminated


Getting closer, please help me out a little bit more. Thanks
Do you know where the "Press (Q: quit...." line comes from?

Have you simplified your script to replace the "expect --exact" lines with ones which look for specific strings?  For example, replace the long login one with 'expect "ogin:"'.  Do you still need the "span /bin/bash", or can you replace it with "spawn telnet"?  The only reason I can see for using "spawn /bin/bash" is if you want to do more than one thing in the script - telnet to the remote host, log out and then do some work locally.

Note that the "expect" after sending the username assumes that the username is echoed to the screen - this may not happen under crontab.  Much better to ignore that bit, and simply wait for the password prompt, as in 'expect "ssword:"'

Please make these changes and send the resulting script and output.
Here is my entire script, I have made changes. I'll give you the log output too, I am getting to Password now, but not getting past it. But once again, running the script manually with ./script.exp runs fine.

#!/usr/bin/expect -f

set force_conservative 0                            
if {$force_conservative} {
        set send_slow {1 .1}
        proc send {ignore arg} {
                sleep .1
                exp_send -s -- $arg
        }
}
set timeout -1
spawn telnet 10.100.72.211
expect "Login:"
send -- "username\r"
send -- "password\r"
expect "Miltonvale# "
send -- "conf\r"
expect "conf\r
Miltonvale(config)# "
send -- "set control db-backup\r"
expect "Miltonvale(config)# "
send -- "logo\r"

Here is the output of the log

spawn telnet 10.100.72.211
Trying 10.100.72.211...
Connected to 10.100.72.211.
Escape character is '^]'.
Login:coleg
                                                                   

Password:                                                          
Press (Q: quit, <cr>: line by line, S: no page, others: continue)





Ok, I have even made my script simpler.
#!/usr/bin/expect

set timeout -1
spawn telnet 10.100.72.211
expect "Login:"
send -- "username\r"
send -- "password\r"
expect "Miltonvale# "
send -- "conf\r"
expect "conf\r
Miltonvale(config)# "
send -- "set control db-backup\r"
expect "Miltonvale(config)# "
send -- "logo\r"

I have figured out what this line is in the log
Press (Q: quit, <cr>: line by line, S: no page, others: continue)
It's what shows up on a show command in the network device. But when I login manually I never see that, I don't know why in a cron it is. Advice????
ASKER CERTIFIED SOLUTION
Avatar of simon3270
simon3270
Flag of United Kingdom of Great Britain and Northern Ireland image

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
I wrote my script according to the above except for the set nopage it is "enable no more"
It works when I run it manually and it prints it on the screen, but through cron it isn't allowing me to get the prompt, here is the cronlog file.

spawn telnet 10.100.72.211
Trying 10.100.72.211...
Connected to 10.100.72.211.
Escape character is '^]'.
Login:coleg
                                                                   

Password:                                                          
Press (Q: quit, <cr>: line by line, S: no page, others: continue


I'm not sure why it's giving me that last line. Is there a way to have cron print to the screen while it is running? Thanks
To make matters a bit worse, it appears that it is not actually sending a password to the device. I can see the characters that are sent in the logs of the Network device, and it's never getting anything.
It may be time to add thr "exp_internal 1" command I mentioned earlier, to see what "expect" thinks is happening.

Alernatively, you could add some lines such as
  send_user "About to send password\n"
to the script (note the \n instead or \r for a newline) to print out what the script is doing.  That way you can see whether is is actually running all the way through.
When I add the "exp_internal 1" string at the end of the script nothing happens. Is that the correct place to add it?
No, at the beginning - it turns debugging at the point it is specified.
Ok, I get the same output in the cronlog.txt file, but when I run it manually it does spit out a lot of stuff. Here it is.

spawn telnet 10.100.72.211
parent: waiting for sync byte
parent: telling child to go ahead
parent: now unsynchronized from child
spawn: returns {24884}

expect: does "" (spawn_id exp4) match glob pattern "Login:"? no
Trying 10.100.72.211...

expect: does "Trying 10.100.72.211...\r\r\n" (spawn_id exp4) match glob pattern "Login:"? no
Connected to 10.100.72.211.
Escape character is '^]'.

expect: does "Trying 10.100.72.211...\r\r\nConnected to 10.100.72.211.\r\r\nEscape character is '^]'.\r\r\n" (spawn_id exp4) match glob pattern "Login:"? no
Login:
expect: does "Trying 10.100.72.211...\r\r\nConnected to 10.100.72.211.\r\r\nEscape character is '^]'.\r\r\nLogin:" (spawn_id exp4) match glob pattern "Login:"? yes
expect: set expect_out(0,string) "Login:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "Trying 10.100.72.211...\r\r\nConnected to 10.100.72.211.\r\r\nEscape character is '^]'.\r\r\nLogin:"
send: sending "coleg\r" to { exp4 }

expect: does "" (spawn_id exp4) match glob pattern "ssword:"? no
u
expect: does "u" (spawn_id exp4) match glob pattern "ssword:"? no
sername
Password:
expect: does "coleg\r\nPassword:" (spawn_id exp4) match glob pattern "ssword:"? yes
expect: set expect_out(0,string) "ssword:"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "coleg\r\nPassword:"
send: sending "password\r" to { exp4 }

expect: does "" (spawn_id exp4) match glob pattern "#"? no


expect: does "\r\n" (spawn_id exp4) match glob pattern "#"? no
Miltonvale#
expect: does "\r\nMiltonvale# " (spawn_id exp4) match glob pattern "#"? yes
expect: set expect_out(0,string) "#"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) "\r\nMiltonvale#"
send: sending "enable no more\r" to { exp4 }

expect: does " " (spawn_id exp4) match glob pattern "#"? no
e
expect: does " e" (spawn_id exp4) match glob pattern "#"? no
nable no more

expect: does " enable no more\r\n" (spawn_id exp4) match glob pattern "#"? no
Miltonvale
expect: does " enable no more\r\nMiltonvale" (spawn_id exp4) match glob pattern "#"? no
#
expect: does " enable no more\r\nMiltonvale# " (spawn_id exp4) match glob pattern "#"? yes
expect: set expect_out(0,string) "#"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " enable no more\r\nMiltonvale#"
send: sending "conf\r" to { exp4 }

expect: does " " (spawn_id exp4) match glob pattern "(config)#"? no
c
expect: does " c" (spawn_id exp4) match glob pattern "(config)#"? no
onf

expect: does " conf\r\n" (spawn_id exp4) match glob pattern "(config)#"? no
Miltonvale(config)
expect: does " conf\r\nMiltonvale(config)" (spawn_id exp4) match glob pattern "(config)#"? no
#
expect: does " conf\r\nMiltonvale(config)# " (spawn_id exp4) match glob pattern "(config)#"? yes
expect: set expect_out(0,string) "(config)#"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " conf\r\nMiltonvale(config)#"
send: sending "set control db-backup\r" to { exp4 }

expect: does " " (spawn_id exp4) match glob pattern "(config)#"? no
s
expect: does " s" (spawn_id exp4) match glob pattern "(config)#"? no
et control db-backup

expect: does " set control db-backup\r\n" (spawn_id exp4) match glob pattern "(config)#"? no


expect: does " set control db-backup\r\n\r\n" (spawn_id exp4) match glob pattern "(config)#"? no
 Set Control done
Miltonvale(config)#
expect: does " set control db-backup\r\n\r\n Set Control done\r\nMiltonvale(config)# " (spawn_id exp4) match glob pattern "(config)#"? yes
expect: set expect_out(0,string) "(config)#"
expect: set expect_out(spawn_id) "exp4"
expect: set expect_out(buffer) " set control db-backup\r\n\r\n Set Control done\r\nMiltonvale(config)#"
send: sending "logo\r" to { exp4 }
I wonder if cronlog.txt is only capturing stdout, not stderr.  "expect" sends its logging info to stderr.  Is there a cronlog.err file (or some name like that) in the same place as the cronlog.txt?

Alternatively, do your own capture by adding
    > /tmp/myexp.log 2>&1
to the end f your crontab line, and look in that file for output.