首页 > 解决方案 > pexpect 捕获多个命令输出

问题描述

我正在尝试了解 pexpect 模块并尝试打印多个命令输出。但它没有给出预期的结果。

import pexpect
def main():
        child = pexpect.spawn('sudo su - bhreddy1')
        child.expect('bhreddy1')
        child.sendline('df -h')
        child.expect('bhreddy1')
        print('\nrunning df -h commnd' )
        print(child.before.decode())
        print('\ncompleted df -h commnd' )
        child.sendline('ls')
        child.expect('bhreddy1')
        child.sendline('exit')
        print('\nrunning ls commnd' )
        print(child.before.decode())
        print('\ncompleted ls commnd' )
        child.interact()

if __name__ == '__main__':
        main()

预期输出:

running df -h commnd
@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            476M     0  476M   0% /dev
tmpfs           100M   11M   89M  11% /run
/dev/sda1       218G  1.9G  205G   1% /
tmpfs           497M     0  497M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           497M     0  497M   0% /sys/fs/cgroup
/dev/sda2       923M   59M  802M   7% /boot
/dev/sda4       266G  306M  252G   1% /home
tmpfs           100M     0  100M   0% /run/user/1001

completed df -h commnd

running ls commnd
bhr
completed ls commnd

实际结果:

running df -h commnd
@ubuntu: ~

completed df -h commnd

running ls commnd
@ubuntu:~$ df -h
Filesystem      Size  Used Avail Use% Mounted on
udev            476M     0  476M   0% /dev
tmpfs           100M   11M   89M  11% /run
/dev/sda1       218G  1.9G  205G   1% /
tmpfs           497M     0  497M   0% /dev/shm
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           497M     0  497M   0% /sys/fs/cgroup
/dev/sda2       923M   59M  802M   7% /boot
/dev/sda4       266G  306M  252G   1% /home
tmpfs           100M     0  100M   0% /run/user/1001


completed ls commnd
@ubuntu: ~bhreddy1@ubuntu:~$ ls
bhr
bhreddy1@ubuntu:~$ exit
logout

有人请建议如何收集多个命令输出。我们是否可以选择仅将命令输出注册到变量并在最后打印该变量。

标签: pythonpython-3.x

解决方案


如果你想@ubuntu: ~从输出中删除等,那么你应该使用.*inexpect()来获得完整的行 - 这应该从输出中删除它

        child.expect('bhreddy1@ubuntu:.*')

import pexpect

def main():
        child = pexpect.spawn('sudo su - bhreddy1')
        child.expect('bhreddy1@ubuntu:.*')

        child.sendline('df -h')
        child.expect('bhreddy1@ubuntu:.*')

        print('\nrunning df -h commnd' )
        print(child.before.decode())
        print('\ncompleted df -h commnd' )

        child.sendline('ls')
        child.expect('bhreddy1@ubuntu:.*')

        print('\nrunning ls commnd' )
        print(child.before.decode())
        print('\ncompleted ls commnd' )

        child.sendline('exit')

        child.interact()

if __name__ == '__main__':
        main()

如果您需要在变量中输出,那么只需使用=+=连接字符串。

您可能还必须\n在每个文本之后添加,因为通常print()\n在末尾添加。

result = ""

# ... code ...

result += '\nrunning df -h commnd\n'
result += child.before.decode() + '\n'
result += '\ncompleted df -h commnd\n'

# ... code ...

result += '\nrunning ls commnd\n'
result += child.before.decode() + '\n'
result += '\ncompleted ls commnd\n'

# ... code ...

print(result)

您也可以将其保留为列表,然后将其全部转换为一个字符串并\n使用"\n".join(list).

result = []

# ... code ...

result.append('\nrunning df -h commnd')
result.append(child.before.decode())
result.append('\ncompleted df -h commnd')

# ... code ...

result.append('\nrunning ls commnd')
result.append(child.before.decode())
result.append('\ncompleted ls commnd')

# ... code ...

text = "\n".join(result)

print(text)


编辑:

如果您不想看到某些结果,则可以使用child.beforewithoutprint()

    child.sendline('exit')
    child.expect('exit')
    child.expect('exit')   # on my system it displays `exit` two times so I need `expect` two times
    child.before.before()  # get output but don't `print()`

顺便提一句:

您重复一些代码,以便您可以创建函数:

import pexpect

def run(child, cmd):
    child.sendline(cmd)
    child.expect('bhreddy1@ubuntu:.*')

    print(f'\nrunning {cmd} commnd' )
    print(child.before.decode())
    print(f'\ncompleted {cmd} commnd' )
    
def main():
    child = pexpect.spawn('sudo su - bhreddy1')
    child.expect('bhreddy1@ubuntu:.*')

    run('df -h')
    
    run('ls')

    child.sendline('exit')
    child.expect('exit')
    child.expect('exit')   # it can display `exit` two times
    child.before.decode()  # get output without `print()`
    
    child.interact()

if __name__ == '__main__':
    main()

推荐阅读