简体   繁体   English

TypeError:&#39;在 <string> &#39;需要将字符串作为左操作数,而不是Telnetlib Python3中的字节

[英]TypeError: 'in <string>' requires string as left operand, not bytes in Telnetlib Python3

Im having a problem with using telenetlib in python 3. Here is my code: 我在python 3中使用telenetlib时遇到问题。这是我的代码:

import time
import os

originalTime=0
state=0

def cleanString(inText):
    inText = inText.rstrip()
    params, inText = inText.split("=",1)
    inText = str(inText)
    return inText

def notify(title, text, sound):
    os.system("""osascript -e 'display notification "{}" with title "{}" sound name "{}"'
              """.format(text, title, sound))

def shutdown():
    os.system("""osascript -e 'tell application "System Events"
    shut down
    end tell'
    """)



dataFile = open("NUT.conf", "r")
login = cleanString(dataFile.readline())
password = cleanString(dataFile.readline())
host = cleanString(dataFile.readline())
port = cleanString(dataFile.readline())
upsName = cleanString(dataFile.readline())
shutdownTime = cleanString(dataFile.readline())

shutdownTime = shutdownTime*60,000

print(login)
print(password)
print(host)
print(port)
print(upsName)
print(shutdownTime)

ups_handler=PyNUT.PyNUTClient(host=host, port=port, login=login, password=password)
upsInfo = ups_handler.GetUPSVars(upsName)

while True:
    upsInfo = ups_handler.GetUPSVars(upsName)

    if upsInfo['ups.status']=='OB DISCHRG' and state!=1:
        originalTime = time.time()
        state=1

    elif upsInfo['ups.status']=='OB DISCHRG' :
        print("PANIC")
        if(int(originalTime)+int(  shutdownTime))==time.time():
            notify("UPS Alert", "Detected UPS power loss. Shutting down NAS in "+shutdownTime+" minute(s).", "Funk")
            #TODO shutdown computer

    if upsInfo['ups.status']=='OL':
        state=0

Here is the pyNUT library: 这是pyNUT库:

 #!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright (C) 2008 David Goncalves <david@lestat.st> # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. # 2008-01-14 David Goncalves # PyNUT is an abstraction class to access NUT (Network UPS Tools) server. # # 2008-06-09 David Goncalves # Added 'GetRWVars' and 'SetRWVar' commands. # # 2009-02-19 David Goncalves # Changed class PyNUT to PyNUTClient # # 2010-07-23 David Goncalves - Version 1.2 # Changed GetRWVars function that fails is the UPS is not # providing such vars. # # 2011-07-05 René Martín Rodríguez <rmrodri@ull.es> - Version 1.2.1 # Added support for FSD, HELP and VER commands # # 2012-02-07 René Martín Rodríguez <rmrodri@ull.es> - Version 1.2.2 # Added support for LIST CLIENTS command # # 2014-06-03 george2 - Version 1.3.0 # Added custom exception class, fixed minor bug, added Python 3 support. # import telnetlib class PyNUTError(Exception): """ Base class for custom exceptions """ class PyNUTClient: """ Abstraction class to access NUT (Network UPS Tools) server """ __debug = None # Set class to debug mode (prints everything useful for debugging...) __host = None __port = None __login = None __password = None __timeout = None __srv_handler = None __version = "1.3.0" __release = "2014-06-03" def __init__( self, host="127.0.0.1", port=3493, login=None, password=None, debug=False, timeout=5 ) : """ Class initialization method host : Host to connect (default to localhost) port : Port where NUT listens for connections (default to 3493) login : Login used to connect to NUT server (default to None for no authentication) password : Password used when using authentication (default to None) debug : Boolean, put class in debug mode (prints everything on console, default to False) timeout : Timeout used to wait for network response """ self.__debug = debug if self.__debug : print( "[DEBUG] Class initialization..." ) print( "[DEBUG] -> Host = %s (port %s)" % ( host, port ) ) print( "[DEBUG] -> Login = '%s' / '%s'" % ( login, password ) ) self.__host = host self.__port = port self.__login = login self.__password = password self.__timeout = 5 self.__connect() # Try to disconnect cleanly when class is deleted ;) def __del__( self ) : """ Class destructor method """ try : self.__srv_handler.write( "LOGOUT\\n" ) except : pass def __connect( self ) : """ Connects to the defined server If login/pass was specified, the class tries to authenticate. An error is raised if something goes wrong. """ if self.__debug : print( "[DEBUG] Connecting to host" ) self.__srv_handler = telnetlib.Telnet( self.__host, self.__port ) if self.__login != None : self.__srv_handler.write( "USERNAME %s\\n" % self.__login ) result = self.__srv_handler.read_until( "\\n", self.__timeout ) if result[:2] != "OK" : raise PyNUTError( result.replace( "\\n", "" ) ) if self.__password != None : self.__srv_handler.write( "PASSWORD %s\\n" % self.__password ) result = self.__srv_handler.read_until( "\\n", self.__timeout ) if result[:2] != "OK" : raise PyNUTError( result.replace( "\\n", "" ) ) def GetUPSList( self ) : """ Returns the list of available UPS from the NUT server The result is a dictionary containing 'key->val' pairs of 'UPSName' and 'UPS Description' """ if self.__debug : print( "[DEBUG] GetUPSList from server" ) self.__srv_handler.write( "LIST UPS\\n" ) result = self.__srv_handler.read_until( "\\n" ) if result != "BEGIN LIST UPS\\n" : raise PyNUTError( result.replace( "\\n", "" ) ) result = self.__srv_handler.read_until( "END LIST UPS\\n" ) ups_list = {} for line in result.split( "\\n" ) : if line[:3] == "UPS" : ups, desc = line[4:-1].split( '"' ) ups_list[ ups.replace( " ", "" ) ] = desc return( ups_list ) def GetUPSVars( self, ups="" ) : """ Get all available vars from the specified UPS The result is a dictionary containing 'key->val' pairs of all available vars. """ if self.__debug : print( "[DEBUG] GetUPSVars called..." ) self.__srv_handler.write( "LIST VAR %s\\n" % ups ) result = self.__srv_handler.read_until( "\\n" ) if result != "BEGIN LIST VAR %s\\n" % ups : raise PyNUTError( result.replace( "\\n", "" ) ) ups_vars = {} result = self.__srv_handler.read_until( "END LIST VAR %s\\n" % ups ) offset = len( "VAR %s " % ups ) end_offset = 0 - ( len( "END LIST VAR %s\\n" % ups ) + 1 ) for current in result[:end_offset].split( "\\n" ) : var = current[ offset: ].split( '"' )[0].replace( " ", "" ) data = current[ offset: ].split( '"' )[1] ups_vars[ var ] = data return( ups_vars ) def GetUPSCommands( self, ups="" ) : """ Get all available commands for the specified UPS The result is a dict object with command name as key and a description of the command as value """ if self.__debug : print( "[DEBUG] GetUPSCommands called..." ) self.__srv_handler.write( "LIST CMD %s\\n" % ups ) result = self.__srv_handler.read_until( "\\n" ) if result != "BEGIN LIST CMD %s\\n" % ups : raise PyNUTError( result.replace( "\\n", "" ) ) ups_cmds = {} result = self.__srv_handler.read_until( "END LIST CMD %s\\n" % ups ) offset = len( "CMD %s " % ups ) end_offset = 0 - ( len( "END LIST CMD %s\\n" % ups ) + 1 ) for current in result[:end_offset].split( "\\n" ) : var = current[ offset: ].split( '"' )[0].replace( " ", "" ) # For each var we try to get the available description try : self.__srv_handler.write( "GET CMDDESC %s %s\\n" % ( ups, var ) ) temp = self.__srv_handler.read_until( "\\n" ) if temp[:7] != "CMDDESC" : raise PyNUTError else : off = len( "CMDDESC %s %s " % ( ups, var ) ) desc = temp[off:-1].split('"')[1] except : desc = var ups_cmds[ var ] = desc return( ups_cmds ) def GetRWVars( self, ups="" ) : """ Get a list of all writable vars from the selected UPS The result is presented as a dictionary containing 'key->val' pairs """ if self.__debug : print( "[DEBUG] GetUPSVars from '%s'..." % ups ) self.__srv_handler.write( "LIST RW %s\\n" % ups ) result = self.__srv_handler.read_until( "\\n" ) if ( result != "BEGIN LIST RW %s\\n" % ups ) : raise PyNUTError( result.replace( "\\n", "" ) ) result = self.__srv_handler.read_until( "END LIST RW %s\\n" % ups ) offset = len( "VAR %s" % ups ) end_offset = 0 - ( len( "END LIST RW %s\\n" % ups ) + 1 ) rw_vars = {} try : for current in result[:end_offset].split( "\\n" ) : var = current[ offset: ].split( '"' )[0].replace( " ", "" ) data = current[ offset: ].split( '"' )[1] rw_vars[ var ] = data except : pass return( rw_vars ) def SetRWVar( self, ups="", var="", value="" ): """ Set a variable to the specified value on selected UPS The variable must be a writable value (cf GetRWVars) and you must have the proper rights to set it (maybe login/password). """ self.__srv_handler.write( "SET VAR %s %s %s\\n" % ( ups, var, value ) ) result = self.__srv_handler.read_until( "\\n" ) if ( result == "OK\\n" ) : return( "OK" ) else : raise PyNUTError( result ) def RunUPSCommand( self, ups="", command="" ) : """ Send a command to the specified UPS Returns OK on success or raises an error """ if self.__debug : print( "[DEBUG] RunUPSCommand called..." ) self.__srv_handler.write( "INSTCMD %s %s\\n" % ( ups, command ) ) result = self.__srv_handler.read_until( "\\n" ) if ( result == "OK\\n" ) : return( "OK" ) else : raise PyNUTError( result.replace( "\\n", "" ) ) def FSD( self, ups="") : """ Send FSD command Returns OK on success or raises an error """ if self.__debug : print( "[DEBUG] MASTER called..." ) self.__srv_handler.write( "MASTER %s\\n" % ups ) result = self.__srv_handler.read_until( "\\n" ) if ( result != "OK MASTER-GRANTED\\n" ) : raise PyNUTError( ( "Master level function are not available", "" ) ) if self.__debug : print( "[DEBUG] FSD called..." ) self.__srv_handler.write( "FSD %s\\n" % ups ) result = self.__srv_handler.read_until( "\\n" ) if ( result == "OK FSD-SET\\n" ) : return( "OK" ) else : raise PyNUTError( result.replace( "\\n", "" ) ) def help(self) : """ Send HELP command """ if self.__debug : print( "[DEBUG] HELP called..." ) self.__srv_handler.write( "HELP\\n") return self.__srv_handler.read_until( "\\n" ) def ver(self) : """ Send VER command """ if self.__debug : print( "[DEBUG] VER called..." ) self.__srv_handler.write( "VER\\n") return self.__srv_handler.read_until( "\\n" ) def ListClients( self, ups = None ) : """ Returns the list of connected clients from the NUT server The result is a dictionary containing 'key->val' pairs of 'UPSName' and a list of clients """ if self.__debug : print( "[DEBUG] ListClients from server" ) if ups and (ups not in self.GetUPSList()): raise PyNUTError( "%s is not a valid UPS" % ups ) if ups: self.__srv_handler.write( "LIST CLIENTS %s\\n" % ups) else: self.__srv_handler.write( "LIST CLIENTS\\n" ) result = self.__srv_handler.read_until( "\\n" ) if result != "BEGIN LIST CLIENTS\\n" : raise PyNUTError( result.replace( "\\n", "" ) ) result = self.__srv_handler.read_until( "END LIST CLIENTS\\n" ) ups_list = {} for line in result.split( "\\n" ): if line[:6] == "CLIENT" : host, ups = line[7:].split(' ') ups.replace(' ', '') if not ups in ups_list: ups_list[ups] = [] ups_list[ups].append(host) return( ups_list ) 

It is throwing me this error: 这使我犯了这个错误:

Traceback (most recent call last):
  File "/Users/gabrielcsizmadia/Documents/GitHub/nut-shutdown-app/main.py", line 43, in <module>
    ups_handler=PyNUT.PyNUTClient(host=host, port=port, login=login, password=password)
  File "/Users/gabrielcsizmadia/Documents/GitHub/nut-shutdown-app/PyNUT.py", line 86, in __init__
    self.__connect()
  File "/Users/gabrielcsizmadia/Documents/GitHub/nut-shutdown-app/PyNUT.py", line 108, in __connect
    self.__srv_handler.write( "USERNAME %s\n" % self.__login )
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/telnetlib.py", line 287, in write
    if IAC in buffer:
TypeError: 'in <string>' requires string as left operand, not bytes
      File "/Users/gabrielcsizmadia/Desktop/Homelab/NUT Shutdown/MacOS Shutdown/PyNUT.py", line 108, in __connect
        self.__srv_handler.write( "USERNAME %s\n" % self.__login )
      File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/telnetlib.py", line 287, in write
        if IAC in buffer:
    TypeError: 'in <string>' requires string as left operand, not bytes

Not sure where to go from here... Any help would be much appreciated! 不确定从这里去哪里...任何帮助将不胜感激!

EDIT: I have updated the error, I posted the wrong error in the original code... I have also added more to the code. 编辑:我已经更新了错误,我在原始代码中发布了错误的错误...我也添加了更多的代码。

I also noticed that it runs fine in Python 2.7 but not Python 3. This might help someone. 我还注意到它在Python 2.7中运行良好,但在Python 3中却没有。这可能对某人有所帮助。

尝试

print(objName.Hello().decode('utf-8'))

The problem is that pyNUT is written for Python 2. telnetlib expects most of its inputs to be bytes . 问题是,被pyNUT为Python写入2. telnetlib预期大部分其输入是字节 In Python 2 the str type was a bytestring, but in Python 3 it's unicode. 在Python 2中, str类型是一个字节字符串,但是在Python 3中,它是unicode。

The pyNUT code is using string literals to format strings internally, like this: pyNUT代码使用字符串文字在内部格式化字符串,如下所示:

self.__srv_handler.write( "USERNAME %s\n" % self.__login ) 

so passing bytes isn't going to help: 因此,传递字节将无济于事:

>>> 'Hello %s' % 'world'.encode('ascii')
"Hello b'world'"

pyNUT needs to be modified to pass bytes to telnetlib. pyNUT需要修改以将字节传递给telnetlib。 For example 例如

self.__srv_handler.write( b"USERNAME %s\n" % self.__login.encode('ascii') ) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类型错误:'在<string> ' 需要字符串作为左操作数,而不是字节,python</string> - TypeError: 'in <string>' requires string as left operand, not bytes,python TypeError:&#39;在 <string> &#39;需要将字符串作为左操作数,而不是方法PYTHON - TypeError: 'in <string>' requires string as left operand, not method PYTHON TypeError:&#39;in <string> &#39;要求字符串作为左操作数而不是列表 - TypeError: 'in <string>' requires string as left operand not list TypeError:&#39;in <string> &#39;需要字符串作为左操作数,而不是QString - TypeError: 'in <string>' requires string as left operand, not QString TypeError:&#39;在 <string> &#39;需要将字符串作为左操作数,而不是QueryDict - TypeError: 'in <string>' requires string as left operand, not QueryDict TypeError:&#39;在 <string> &#39;需要将字符串作为左操作数,而不是布尔值 - TypeError: 'in <string>' requires string as left operand, not bool 类型错误:&#39;在<string> &#39; 需要字符串作为左操作数,而不是元组 - TypeError: 'in <string>' requires string as left operand, not tuple TypeError:&#39;在 <string> &#39;需要将字符串作为左操作数而不是int - TypeError: 'in <string>' requires string as left operand not int 类型错误:&#39;在<string> &#39; 需要字符串作为左操作数,而不是 Series - TypeError: 'in <string>' requires string as left operand, not Series 类型错误:'在<string> ' 需要字符串作为左操作数,而不是 NoneType</string> - TypeError: 'in <string>' requires string as left operand, not NoneType
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM