因此,我目前正在尝试使脚本运行,但手动运行脚本时的行为与从 crontab 运行脚本时的行为不同。基本上,我设置了从一台服务器到另一台服务器的反向 ssh 隧道,为了验证隧道是否已启动,我:
- 从服务器 A SSH 到服务器 B
- 从服务器 B 获取服务器 A 上的测试 URL
- 如果 Wget 成功,我将断开连接并且不执行任何操作
- 如果 Wget 失败,我将断开连接并重新启动隧道
我知道有更优雅的方法来验证 ssh 隧道(例如 autossh 和 ServerKeepAlive),但对于策略和冗余问题,我必须这样做。无论如何,这是脚本:
from __future__ import print_function
from __future__ import absolute_import
import os, sys, subprocess, logging, pexpect
COMMAND_PROMPT = '[#$] '
TERMINAL_PROMPT = '(?1)terminal type\?'
TERMINAL_TYPE = 'vt100'
SSH_NEWKEY = '(?i)are you sure you want to continue connecting'
SERVERS = [{address':'192.168.100.10', 'connString':'ssh [email protected]', 'testGet':'wget http://192.168.100.11/test.html -t 1 -T 10', 'tunnel':'start_tunnel'}, {address':'192.168.100.12', 'connString':'ssh [email protected]', 'testGet':'wget http://192.168.100.13/test.html -t 1 -T 10', 'tunnel':'start_tunnel2'}]
def main():
global COMMAND_PROMPT, TERMINAL_PROMPT, TERMINAL_TYPE, SSH_NEWKEY, SERVERS
#set up logging
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
handler = logging.FileHandler('/home/user/tunnelTest.log')
formatter = logging.Formatter('%(asctime)s - %(module)s.%(funcName)s: %(message)s')
handler.setFormatter(formatter)
log.addHandler(handler)
for x in SERVERS:
#connect to server
child = pexpect.spawn(x['connString'])
i = child.expect([pexpect.TIMEOUT, SSH_NEWKEY, COMMAND_PROMPT, '(?i)password'])
if i == 0: #Timeout
log.debug('ERROR! Could not log in to ' + x['address'] + ' ...')
sys.exit(1)
if i = 1: #No key cached
child.sendline('yes')
child.expect(COMMAND_PROMPT)
log.debug('Connected to ' + x['address'] + '...')
if i = 2: #Good to go
log.debug('Connected to ' + x['address'] + '...')
pass
#Housecleaning
child.sendline('cd /tmp')
child.expect(COMMAND_LINE)
child.sendline('rm -r test.html')
child.expect(COMMAND_LINE)
log.debug('Testing service using ' + x['testGet'] + ' ...')
child.sendline(x['testGet'])
child.expect(COMMAND_PROMPT)
if 'saved' in child.before.lower():
log.debug('Tunnel working, nothing to do here!')
log.debug('Disconnecting from remote host ' + x['address'] + '...')
child.sendline('exit')
else:
log.error('Tunnel down!')
log.debug('Disconnecting from remote host ' + x['address'] + ' and restarting tunnel')
child.sendline('exit')
subprocess.call(['start',x['tunnel']])
log.debug('Autossh tunnel restarted')
if __name__ == "__main__":
main()
我的 crontab 条目如下:
0,30 * * * * python /home/user/tunnelTest.py
所以是的——当我手动执行此脚本(sudo python tunnelTest.py)时,它运行良好,在 crontab 上也能正常运行,除非隧道关闭。当隧道关闭时,我的日志中会收到“隧道关闭!”和“断开与远程主机 192.168.100.10 的连接并重新启动隧道”消息,但脚本似乎就此挂了。隧道不会重新启动,在下一次计划运行开始之前,我的日志中不会收到任何消息。
start_tunnel 脚本在 /etc/init 中,testTunnel.py 脚本在 /home/user 中,testTunnel.log 文件在 /home/user/logs 中,我以 root 身份运行 crontab -e。
对此事的任何见解都将不胜感激。
谢谢!
答案1
您需要使用 python 的完整路径,例如
/usr/bin/python
你可以找到路径which python
因此你的 crontab 条目将如下所示
0,30 * * * * /usr/bin/python /home/user/tunnelTest.py