| 关键词:time sshConStatus shutdown Paramiko 如果 itchat SSH filehelper ToUserName 成功 |
作者 | 阿文 责编 | 伍杏玲 有时候需要远程家里的台式机使用,因为我平时都是用 MAC 多,但是远程唤醒只能针对局域网,比较麻烦,于是我想用微信实现远程唤醒机器。 准备工作 本程序主要是实现远程管理 Windows10操作系统的开机和关机:
开机实现思路 首先通过微信发送开机指令,这里我使用的是 itchat 程序会调用 Paramiko 库去 SSH 远程到内网的树莓派执行 WakeOnLan 命令去唤醒 Windows 主机。 pi@raspberrypi:~ $ wakeonlan -i 192.168.1.0 14:dd:a9:ea:0b:96 Sending magic packet to 192.168.1.0:9 with 14:dd:a9:ea:0b:96 程序会通过 ICMP 协议, ping 下需要唤醒的目标主机然后进行过滤,一个正常的 ICMP 包是64字节,过滤打印出这个64。 例如 ping 百度: �7�4 ~ ping www.baidu.com PING www.a.shifen.com (180.97.33.108): 56 data bytes 64 bytes from 180.97.33.108: icmp_seq=0 ttl=53 time=8.865 ms 64 bytes from 180.97.33.108: icmp_seq=1 ttl=53 time=9.206 ms 64 bytes from 180.97.33.108: icmp_seq=2 ttl=53 time=8.246 ms 用一段 Linux 命令去过滤是否有64,这里为啥要用 head -n 1 呢? 因为有可能会出现2行,经过测试,我们只需要取64这个值就可以了: ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1 如果有则表示开机成功已经联网了,返回开机成功,否则程序继续往下走,去唤醒,然后在 ping 一次确认是否开机,如果为是则返回开机成功,否则返回失败。程序执行成功后,在我的网站根目录创建一个 shutdown 文件,用于后面的关机操作: #!/usr/bin/python
# -*- coding: utf-8 -*-
import itchat
import paramiko
import os
import time
import sys
reload(sys)
sys.setdefaultencoding(utf-8)
hostname =
username =
port =
key_file = /home/fangwenjun/.ssh/id_rsa
filename = /home/fangwenjun/.ssh/known_hosts
@itchat.msg_register(itchat.content.TEXT)
def text_reply(msg):
if msg[ToUserName] != filehelper: return
if msg[Text] == u开机:
paramiko.util.log_to_file(ssh_key-login.log)
privatekey = os.path.expanduser(key_file)
try:
key = paramiko.RSAKey.from_private_key_file(privatekey)
except paramiko.PasswordRequiredException:
key = paramiko.RSAKey.from_private_key_file(privatekey,key_file_pwd)
ssh = paramiko.SSHClient()
ssh.load_system_host_keys(filename=filename)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=hostname,username=username,pkey=key,port=port)
#执行唤醒命令
stdin,stdout,stderr=ssh.exec_command(ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1)
sshCheckOpen = stdout.read()
sshCheckOpen =sshCheckOpen.strip(\n)
print type(sshCheckOpen)
print sshCheckOpen
#进行判断,如果为64,则说明 ping 成功,说明设备已经在开机状态,程序结束,否则执行唤醒
if sshCheckOpen == 64:
connect_ok_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(connect_ok_time+u设备已经开机, toUserName=filehelper)
else:
ssh_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(ssh_time+u开始连接远程主机, toUserName=filehelper)
stdin,stdout,stderr=ssh.exec_command(wakeonlan -i 192.168.1.0 14:dd:a9:ea:0b:96)
wakeonlan_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(wakeonlan_time+u执行唤醒,等待设备开机联网, toUserName=filehelper)
#由于开机需要一些时间去启动网络,所以这里等等60s
time.sleep(60)
#执行 ping 命令,-c 1 表示只 ping 一下,然后过滤有没有64,如果有则获取64传给sshConStatus
stdin,stdout,stderr=ssh.exec_command(ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1)
sshConStatus = stdout.read()
sshConStatus =sshConStatus.strip(\n)
print type(sshConStatus)
print sshConStatus
#进行判断,如果为64,则说明 ping 成功,设备已经联网,可以进行远程连接了,否则发送失败消息
if sshConStatus == 64:
connect_ok_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(connect_ok_time+u设备唤醒成功,您可以远程连接了, toUserName=filehelper)
else:
connect_err_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(connect_err_time+u设备唤醒失败,请检查设备是否连接电源, toUserName=filehelper)
ssh.close()
#在网站根目录创建一个空文件,命名为 shutdown
os.system(touch /www/shutdown)
print 执行开机消息成功
![]() 关机部分实现 当接收关机指令时,程序会去删除网站根目录的 shutdown 文件,客户端我写了几行代码,去通过 Requests 库每隔30s 发送 HTTP head 请求去判断文件是否是404,如果是404 这说明文件不存在,调用系统关机操作,执行关机。 然后 SSH 到树莓派去 ping 目标主机,如果返回为空,则说明关机成功,否则关机失败。这只是针对 Windows 的关机,如果目标主机是 Linux 则简单多了: if msg[Text] == u关机:
#删除网站根目录的shutdown 文件
rmfile = os.system(rm -rf /www/shutdown)
if rmfile == 0:
print 执行关机消息成功
shutdown_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(shutdown_time+u正在关机...., toUserName=filehelper)
paramiko.util.log_to_file(ssh_key-login.log)
privatekey = os.path.expanduser(key_file)
try:
key = paramiko.RSAKey.from_private_key_file(privatekey)
except paramiko.PasswordRequiredException:
key = paramiko.RSAKey.from_private_key_file(privatekey,key_file_pwd)
ssh = paramiko.SSHClient()
ssh.load_system_host_keys(filename=filename)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=hostname,username=username,pkey=key,port=port)
itchat.send(shutdown_time+u正在确认设备是否完成关机操作,大约需要等待60s., toUserName=filehelper)
#等等60秒后确认,因为关机需要一段时间,如果设置太短,可能网络还没断开
time.sleep(60)
stdin,stdout,stderr=ssh.exec_command(ping 192.168.1.182 -c 1 | grep 64 | cut -d " " -f 1|head -n 1)
sshConStatus = stdout.read()
sshConStatus =sshConStatus.strip(\n)
print type(sshConStatus)
print sshConStatus
#如果获取的值为空,则说明已经关机,否则关机失败
if sshConStatus != 64:
shutdown_success_err_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(shutdown_success_err_time+u关机成功, toUserName=filehelper)
else:
shutdown_err_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
itchat.send(shutdown_err_time+u关机失败,请连接桌面检查客户端程序是否正常执行, toUserName=filehelper)
ssh.close()
itchat.auto_login(hotReload=True,enableCmdQR=2)
itchat.run()
![]() 客户端代码,写完扔计划任务,开机启动: import requests
import os
import time
while 1:
time.sleep(30)
r = requests.head("https://awen.me/shutdown")
print r.status_code
if r.status_code == 404:
os.system("shutdown -s -t 5")
使用 TeamViewer 连接: ![]() 缺点
|
| 本文出处: https://www.toutiao.com/a6660749820669461006/ |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|