如何通过pexpect发送命令时避免冗余?

时间:2015-12-21 11:30:46

标签: python pexpect

我有一个python的pexpect代码,它会发送文件中列出的一些命令。

假设我将一些命令存储在名为commandbase

的文件中
ls -l /dev/
ls -l /home/ramana
ls -l /home/ramana/xyz
ls -l /home/ramana/xxx
ls -l /home/ramana/xyz/abc
ls -l /home/ramana/xxx/def
ls -l /home/dir/

等等。

请注意,我/devhome为变量。如果我再次home ramanadir作为变量。如果进入ramana,则会再次xyzxxx。所以基本上它的形式是

ls -l /variable1/variable2/variable3/ 

等等。在这里,我需要为每个变量及其特定的辅助变量构建一个树。

现在我应该有一个list / array / file,我将第一个变量及其辅助变量存储在另一个列表中,依此类推。

所以我需要一个像这样的函数

在主脚本中

for line in database:
             child.sendline(line+"\r")
             child.expect("\$",timeout)

数据库文件应该是:

 def commands():
        return "ls -l <some variable>/<second variable and so on>"

此函数应返回包含所有组合的所有命令

如何在此处返回变量命令而不是定义所有命令?是否可以使用数组或列表?

[编辑]编辑,因为它不太清楚。希望这次我很清楚

3 个答案:

答案 0 :(得分:2)

这可以通过列表理解来完成......

paths = ['/dev/', '/dev/ramana/', ...]
command = 'ls -l'
commandsandpaths = [command + ' ' + x for x in paths]

commandsandpaths将是一个包含...

的列表
ls -l /dev/
ls -l /dev/ramana/

就个人而言,我更喜欢使用字符串格式而不是字符串连接......

commandsandpaths = ['{0} {1}'.format(command, x) for x in paths]

但是,如果您不熟悉语法

,则可能性较差

答案 1 :(得分:1)

不确定您所说的这些变量是什么。它们看起来像我的路径段。

假设您有一个由节点组成的树数据结构,其中每个节点都是一个路径段的元组,以及一个子树列表:

tree = [
    ('dev', []),
    ('home', [
        ('ramana', [
            ('xyz', [
                ('abc', []),
            ]),
            ('xxx', [
                ('def', []),
            ]),
        ]),
        ('dir', []),
    ]),
]

您可以编写一个递归生成器函数来遍历树以生成所有路径:

import os
import os.path

def walk_tree(tree):
    for name, subtree in tree:
        yield name
        for path in walk_tree(subtree):
            yield os.path.join(name, path)

然后您可以生成所有命令:

commands = ['ls -l {path}'.format(path=os.sep + path) for path in walk_tree(tree)]

注意,这段代码不是数据库,它是可以生成数据库的代码。此外,显示的代码以深度优先顺序遍历树,这与您显示的顺序不同(这似乎是深度优先和广度优先的某种组合)。

答案 2 :(得分:0)

您的要求比初看起来要复杂一些。下面我采用了一个约定来使用列表[...]来表示要连接的东西,使用元组(...)来表示可供选择的事物,即选项。

您的路径名列表现在可以表示为: -

database = (
    'dev',
    ['home', (
            'dir',
            ['ramana', (
                    '',
                    ['xyz', (
                            '',
                            'abc'
                        )
                    ],
                    ['xxx', (
                            '',
                            'def'
                        )
                    ]
                   )
            ]
         )
    ]
)

上述语法尽可能避免冗余。空格不是必需的,但可以帮助说明哪些部分位于同一嵌套级别。

接下来,我们需要一种方法将其转换为命令列表: -

def permute(prefix, tree):
    def flatten(branch):
        #print 'flatten', branch
        results = [ ]
        if type(branch) is list:
            parts = [ ]
            for part in branch:
                if type(part) is basestring:
                    if part:
                        parts.append([part])
                else:
                    parts.append(flatten(part))

            index = map(lambda x: 0, parts)
            count = map(len, parts)
            #print 'combining', parts, index, count
            while True:
                line = map(lambda i: parts[i][index[i]],
                       range(len(parts)))
                line = '/'.join(line)
                #print '1:', line
                results.append( line )
                curIndex = len(parts)-1
                while curIndex >= 0:
                    index[curIndex] += 1
                    if index[curIndex] < count[curIndex]:
                        break
                    index[curIndex] = 0
                    curIndex -= 1
                if curIndex < 0:
                    break
        elif type(branch) is tuple:
            for option in branch:
                if type(option) is basestring:
                    if len(option):
                        #print '2:', option
                        results.append( option )
                else:
                    results.extend(flatten(option))
        else:
            #print '3:', branch
            results.append( branch )
        return results

    return map(lambda x: prefix + x, flatten(tree))

现在,如果我们调用permute('ls -l /', database),它将返回以下列表: -

[
    'ls -l /dev', 
    'ls -l /home/dir', 
    'ls -l /home/ramana/', 
    'ls -l /home/ramana/xyz/', 
    'ls -l /home/ramana/xyz/abc', 
    'ls -l /home/ramana/xxx/', 
    'ls -l /home/ramana/xxx/def'
]

从这里开始,将这些字符串写入名为commandbase的文件或逐行执行它是显而易见的。