有没有一种执行命令然后继续程序而不终止命令的方法

Is there a method of executing a command then continue the program without command termination

你好,我正在尝试创建一个函数,它使用 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")

test.c文件是数据包嗅探脚本。它只会以 CTRL-C(或等效方法)终止。它不会终止 naturally/eventually.

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

startPacketReceiver()
...
stopPacketReceiver()

目前,当我 运行 python 脚本时,我从未收到“完成”打印消息,这意味着该程序挂在 exec_command 上,并且在它完成之前不会继续已终止。

附加信息

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 它。

我建议看看daemon(3)

然后你可以捕获SIGNALS或者重新打开标准输入。 取决于您想用 python 脚本做什么。 (如果你不想使用任何 python 除了 sys 和 os 之外的任何 python 库)

编辑:

我很确定 python 脚本何时终止 ssh 连接显然会 close 以及启动连接的用户在那个 tty 上的任何程序 运行将被终止。 出于这个原因,您的 c 程序需要被守护进程并且可能需要 更改其 uid and/or euid。

尽管我尝试重现您的代码并且 运行 遇到了类似的问题:python 脚本是 运行 命令然后打印“完成” 但是当我试图读取标准输出时,整个脚本都暂停了。 我认为它正在等待脚本 return 状态。 所以我做了以下更改:

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程序的输出。 但是,如果您 close python 脚本,c 程序将遵循。 我没有深入研究这个库。

编辑 2:

查找nohup

如果您不想使用 de daemon 方法。

您需要将密码发送至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())