是否有一种方法可以执行命令,然后继续执行程序而不终止命令

2024-06-30 05:31:33 发布

您现在位置:Python中文网/ 问答频道 /正文

嗨,我正在尝试创建一个函数,它使用paramiko和ssh在我的raspberry pi上远程执行我的包嗅探脚本

def startPacketReceiver():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(AutoAddPolicy())
    ssh.connect(RECV_IP_ADDRESS, username="pi", password="raspberry")
    ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command("sudo gcc Code/test.c && sudo ./a.out")
    print("Done")

c文件是包嗅探脚本。它将仅以CTRL-C(或等效方法)终止。它不会自然/最终终止

我希望能够启动接收器,然后退出接收器,例如:

startPacketReceiver()
...
stopPacketReceiver()

目前,当我运行python脚本时,我从未收到“Done”打印消息,这意味着程序挂起在exec_命令上,并且在终止之前不会继续

其他信息

test.c文件无限循环,本质上是:

while(1)
{
    saddr_size = sizeof saddr;
    //Receive a packet
    data_size = recvfrom(sock_raw , buffer , 65536 , 0 , &saddr , (socklen_t*)&saddr_size);
    //fprintf(stderr,"%d",data_size);
    if(data_size <0 )
    {
        fprintf(stderr,"Failed to get packet\n");
        printf("Recvfrom error , failed to get packets\n");
        return 1;
    }
    //Now process the packet
    ProcessPacket(buffer , data_size);
}

所以要阻止它,你必须按住CTRL-C键


Tags: test脚本paramikodatasizepacketstderrpi
2条回答

您需要将密码发送到sudo命令。请通过将get_pty = True参数传递给exec_command函数调用,启用tty模式以执行命令。然后您需要通过ssh_stdin文件接口传递密码

def startPacketReceiver():
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(AutoAddPolicy())
    ssh.connect(RECV_IP_ADDRESS, username="pi", password="raspberry")
    ssh.stdin, ssh_stdout, ssh_stderr = ssh.exec_command("gcc Code/test.c && sudo ./a.out", get_pty=True)
    print("raspberry", ssh_stdin) # Your password for sudo command
    print("Done")
    return ssh, ssh_stdin, ssh_stdout, ssh_stderr

然后您可以编写stopPacketReceiver来发送Ctrl-C信号

def stopPacketReceiver(ssh, ssh_stdin, ssh_stdout, ssh_stderr):
    print('\x03', file=ssh_stdin) # Send Ctrl-C signal
    print(ssh_stdout.read()) #print the stdout
    print(ssh_stderr.read())

我建议看一下daemon(3)

然后您可以捕获信号或重新打开标准输入。 取决于您希望对python脚本执行的操作。 (如果您不想使用任何python,请使用除sys和os以外的任何python库)

编辑:

我非常确定,当python脚本终止ssh连接时,ssh连接将明显关闭,因此启动连接的用户在该tty上运行的任何程序都将终止。 因此,您的c程序需要后台监控,并且可能需要 更改其uid和/或euid

尽管我试图重现您的代码,但我遇到了类似的问题:python脚本运行命令,然后打印“完成” 但当我试图阅读stdout时,整个脚本都停顿了。 我认为它正在等待脚本返回状态。 所以我做了以下改变:

try:
    port = '22'
  
    client = paramiko.SSHClient()
  
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
  
    client.connect('<host_name>', port=22, username='<username>',
                   password='<password>')
  
    chan = client.get_transport().open_session()
    chan.get_pty()
    chan.exec_command("cd <script_directory>;\
                ; gcc test.c; ./a.out")
    while True:
        print(chan.recv(1024))
  
finally:
    client.close()

这里的while循环用于获取c程序的输出。 但是,如果关闭python脚本,c程序将随之运行。 我对这个图书馆没有深入研究

编辑2:

查找nohup

如果您不想使用dedaemon方法

相关问题 更多 >