从异常中获取数据

时间:2012-07-20 00:44:15

标签: python list exception slice

我在切换包含不存在项目的列表时遇到了问题。 正如预期的那样,会出现 IndexError 异常,但我不想对列表中的每个切片执行try和except语句。在upcomong代码中 self.uptime

以下是代码:

import datetime
from urllib2 import urlopen, URLError

from core.libs.menu import Colors
from core.libs.request_handler import make_request


class TargetBox(object):
    def __init__(self, url=None):
        self.url = url
        self.cmd = 'whoami;'
        self.cmd += 'id;'
        self.cmd += 'uname -a;'
        self.cmd += 'pwd;'
        self.cmd += 'ls -ld `pwd` | awk \'{print $1}\';'
        self.cmd += 'bash -c "input=\$(uptime); if [[ \$input == *day* ]]; then out=\$(echo \$input | awk \'{print \$3\\" days\\"}\'); if [[ \$input == *min* ]]; then out=\$(echo \\"\$out and \\" && echo \$input | awk \'{print \$5\\" minutes\\"}\'); else out=\$(echo \\"\$out, \\" && echo \$input | awk \'{print \$5}\' | tr -d \\",\\" | awk -F \\":\\" \'{print \$1\\" hours and \\"\$2\\" minutes\\"}\'); fi elif [[ \$input == *min* ]]; then out=\$(echo \$input | awk \'{print \$3\\" minutes\\"}\'); else out=\$(echo \$input | awk \'{print \$3}\' | tr -d \\",\\" | awk -F \\":\\" \'{print \$1\\" hours and \\"\$2\\" minutes\\"}\'); fi; echo \$out;" ;'
        self.cmd += "/sbin/ifconfig | grep -e 'inet addr' | grep -v '127.0.0.1' | cut -f2 -d':' | cut -f1 -d' ';"

        self.available_commands = ['@backdoor', '@download', '@enum', '@history', '@info', '@update', '@upload', 'clear', 'exit']

    def get_information(self):
        now = datetime.datetime.now()

        # Call get_page_source() method then assign it to self.source
        source = make_request.get_page_source(self.cmd)

        self.current_user = source[0]
        self.current_id = source[1]
        self.kernel_info = source[2]
        self.cwd = source[3]
        self.perm_cwd = source[4]
        try:
            self.uptime = source[5]
        except IndexError:
            self.uptime = 'Unknown'
        self.host_ip = ', '.join(source[6:])
        self.session = now.strftime("%Y-%m-%d")
        try:
            # Get the attacker's ip address (Thanks @mandreko)
            self.local_ip = (urlopen('http://ifconfig.me/ip').read()).strip()
        except URLError:
            self.local_ip = 'Unknown'

        self.info = \
        '''
        {dashed}
        {red}User{end}        :  {green}{current_user}{end}
        {red}ID{end}          :  {green}{current_id}{end}
        {red}Kernel{end}      :  {green}{kernel_info}{end}
        {red}CWD{end}         :  {green}{cwd}{end}\t\t{hot}{perm_cwd}{end}
        {red}Uptime{end}      :  {green}{uptime}{end}
        {red}Target's IPs{end}:  {green}{host_ip}{end}
        {red}Our IP{end}      :  {green}{local_ip}{end}
        {dashed}

        {hot}[+] Available commands: {available_commands}{end}
        {hot}[+] Inserting{end} {red}!{end} {hot}at the begining of the command will execute the command locally ({red}on your box{end}){end}
        '''.format(dashed='-' * int(len(self.kernel_info) + 16),
                red=Colors.RED, green=Colors.GREEN, end=Colors.END, hot=Colors.HOT,
                current_user=self.current_user,
                current_id=self.current_id,
                kernel_info=self.kernel_info,
                cwd=self.cwd,
                perm_cwd=self.perm_cwd,
                host_ip=self.host_ip,
                local_ip=self.local_ip,
                uptime=self.uptime,
                available_commands=self.available_commands,)
        print self.info

info = TargetBox()

我可以在整个变量块上使用该语句吗? e.g。

try:
    self.current_user = source[0]
    self.current_id = source[1]
    self.kernel_info = source[2]
    self.cwd = source[3]
    self.perm_cwd = source[4]
    self.uptime = source[5]
except IndexError:
    self.var_name = 'Unknown'

2 个答案:

答案 0 :(得分:3)

将值预先初始化为其回退/默认值,然后在抛出异常时无需执行任何操作。

self.current_user = None
self.current_id = None
self.kernel_info = None
self.cwd = None
self.perm_cwd = None
self.uptime = 'Unknown'

try:
    self.current_user = source[0]
    self.current_id = source[1]
    self.kernel_info = source[2]
    self.cwd = source[3]
    self.perm_cwd = source[4]
    self.uptime = source[5]
except IndexError:
    pass

当然,根据您的具体情况,将None更改为其他内容。

你也可以使用一个函数来返回指定索引处的元素,否则返回一些默认值:

def get_index_with_default(seq, index, default=None):
    try:
        return seq[index]
    except:
        return default

然后您可以这样方式执行分配:

self.uptime = get_index_with_default(source, 5, 'Unknown')

答案 1 :(得分:2)

try/except在很多时候都是一种有用的Pythonic方法,但在这种情况下,我会采用不同的方法,只为每个不在原始列表中的值分配默认值。如果你使用迭代器和内置next(),你可以自然地实现这一点:

source = iter(source)
self.current_user = next(source, "Unknown")
self.current_id = next(source, "Unknown")
self.kernel_info = next(source, "Unknown")
self.cwd = next(source, "Unknown")
self.perm_cwd = next(source, "Unknown")
self.uptime = next(source, "Unknown")

另一种实现此目的的方法是在列表中添加“未知”,直到达到所需的长度:

from itertools import repeat
source.extend(repeat("Unknown", 6 - len(source) if len(source) < 6 else 0))
self.current_user, self.current_id, self.kernel_info, self.cwd, self.perm_cwd, self.uptime = source