Home > Back-end >  Run remote long running command with Paramiko, feed it with some input and put it to the background
Run remote long running command with Paramiko, feed it with some input and put it to the background

Time:01-14

I have a long running program on my remote server, which I want to start with Paramiko.

I know how to start a program in the background (with nohup for example) but my program first needs a few user inputs. In a normal SSH session I would pass those interactively over the terminal and then detach (Ctrl Z, bg, detach) but I can't do this with Paramiko.

Here is what I've been trying so far:

stdin, stdout, stderr = ssh.exec_command('MyCommand', get_pty=True)
stdin.channel.send(b'MyData\r')
stdin.channel.send(b'\x1A')  # This is Ctrl Z
ssh.exec_command('bg; disown')
ssh.close()

but when the SSH connection closes, the remote program also stops running. How can I send user input to a program, that I want to continue running in the background?

CodePudding user response:

You are currently executing MyCommand and bg; disown in two separate shell instances. That's why the bg; disown has no effect on the MyCommand.

If you really want to emulate the interactive shell features this way, them you need to execute both command in one real shell instance. For that you will need to use SSHClient.invoke_shell and not SSHClient.exec_command.


Though in general, that's not a good idea. See also:
What is the difference between exec_command and send with invoke_shell() on Paramiko?

If the program is yours, modify it to allow getting input from command-line.

If you cannot modify it, use shell constructs to provide the input, like:

ssh.exec_command('nohup echo MyData | MyCommand >/dev/null 2>&1 &')

Maybe you need to add quotes around the command, I'm not sure, what's the "operator precedence" here.

  • Related