如何在没有生成任何数据的情况下终止长期运行的脚本,我尝试通过paramiko模块在Windows控制台中按Ctrl + C.

时间:2021-06-09 20:43:00

This is really interesting. I have following scripts on my linux machine:

这真的很有趣。我的linux机器上有以下脚本:

sleep.py

import time
from datetime import datetime
print(datetime.now())
time.sleep(20)
print('Over!')
print(datetime.now())

loop.py

import time
for i in range(20):
    time.sleep(1)
    print(i)

I can terminate them directly by ctrl+c if I login through PuTTY or git-bash. But when I trying to run the Python scripts on Windows console:

如果我通过PuTTY或git-bash登录,我可以通过ctrl + c直接终止它们。但是当我尝试在Windows控制台上运行Python脚本时:

test.py

def ssh_pty_command(cmd, ip, username, passwd=None, key_filename=None):
    """run ssh.exec_command with realtime output and return exit_code."""
    try:
        ssh = paramiko.SSHClient()
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        logging.debug('Connecting to remote server {}...'.format(ip))
        ssh.connect(ip, 22, username, password=passwd,
                    key_filename=key_filename, timeout=5)
        stdin, stdout, stderr = ssh.exec_command(cmd, get_pty=True)
        logging.info('ssh_In: {}'.format(cmd))
        # print '$: {}'.format(cmd)
        for line in iter(stdout.readline, ""):
            logging.info('ssh_Out: {}'.format(
                line.rstrip('\n').encode('utf-8')))
        for err in iter(stderr.readline, ""):
            logging.error('ssh_Error: {}'.format(
                err.rstrip().encode('utf-8')))
        exit_code = stdout.channel.recv_exit_status()
        logging.debug('Task exit with code {}.\n'.format(exit_code))
        return exit_code
    except Exception as err:
        logging.error('*** Caught SSH exception: %s: %s' %
                      (err.__class__, err))
        raise
    finally:
        ssh.close()

  ssh_pty_command('python loop.py',ip,username)
  ssh_pty_command('python sleep.py',ip,username)

When I press ctrl+c , the loop.py terminated immediately, but the sleep.py waits until the time.sleep(20) is finished and then terminate the execution. How can I terminate the sleep.py immediately?

当我按ctrl + c时,loop.py立即终止,但sleep.py等待,直到time.sleep(20)结束,然后终止执行。我怎样才能立即终止sleep.py?

Note I did try to use get_pty=True in my exec_command method in my function, but it didn't help. I guess it should have something to do with the signal sent by Paramiko, but not sure where to dig in...

注意我确实尝试在我的函数的exec_command方法中使用get_pty = True,但它没有帮助。我想它应该与Paramiko发送的信号有关,但不知道在哪里挖...

1 个解决方案

#1


0  

Ctrl+C signals an interrupt. Python interpreter checks for the interrupt regularly, and raises KeyboardInterrupt exception, when it detects one.

Ctrl + C表示中断。 Python解释器定期检查中断,并在检测到时引发KeyboardInterrupt异常。

When Paramiko is waiting for an incoming data on a socket, the checking for interrupts is probably suspended (just guessing). So if a remote command is not producing any output, you cannot break the local script.

当Paramiko正在等待套接字上的传入数据时,可能会暂停检查中断(只是猜测)。因此,如果远程命令没有产生任何输出,则无法破坏本地脚本。

Your loop.py produces an output using print(i), so your local Python script can be interrupted at the moment it's processing the output.

loop.py使用print(i)生成输出,因此您的本地Python脚本在处理输出时可能会被中断。

In any case, it's not the remote script that cannot be interrupted, it's the local script. So it has probably nothing to do with time.sleep as such.

在任何情况下,它都不是无法中断的远程脚本,而是本地脚本。所以它可能与time.sleep无关。

See also:


If you actually do not want to wait for the command to finish, your question is not really about Python (nor Paramiko), but about Linux. See Execute remote commands, completely detaching from the ssh connection.

如果你真的不想等待命令完成,你的问题不是关于Python(也不是Paramiko),而是关于Linux。请参阅执行远程命令,从ssh连接中完全分离。

#1


0  

Ctrl+C signals an interrupt. Python interpreter checks for the interrupt regularly, and raises KeyboardInterrupt exception, when it detects one.

Ctrl + C表示中断。 Python解释器定期检查中断,并在检测到时引发KeyboardInterrupt异常。

When Paramiko is waiting for an incoming data on a socket, the checking for interrupts is probably suspended (just guessing). So if a remote command is not producing any output, you cannot break the local script.

当Paramiko正在等待套接字上的传入数据时,可能会暂停检查中断(只是猜测)。因此,如果远程命令没有产生任何输出,则无法破坏本地脚本。

Your loop.py produces an output using print(i), so your local Python script can be interrupted at the moment it's processing the output.

loop.py使用print(i)生成输出,因此您的本地Python脚本在处理输出时可能会被中断。

In any case, it's not the remote script that cannot be interrupted, it's the local script. So it has probably nothing to do with time.sleep as such.

在任何情况下,它都不是无法中断的远程脚本,而是本地脚本。所以它可能与time.sleep无关。

See also:


If you actually do not want to wait for the command to finish, your question is not really about Python (nor Paramiko), but about Linux. See Execute remote commands, completely detaching from the ssh connection.

如果你真的不想等待命令完成,你的问题不是关于Python(也不是Paramiko),而是关于Linux。请参阅执行远程命令,从ssh连接中完全分离。