Assume there exists a python script resolve_ip.py which magically returns the string IP of a machine we care about.
I'm interested in learning how to achieve the python equivalent of the following bash command:
user#host:~$ ssh $(./resolve_ip.py)
In this bash example, after the python script runs, it is replaced or rather substituted with its return value which is, in turn, provided as a input to the program ssh. The result is, the python program terminates and the user interacts with ssh initialization.
The problem is, this solution requires the use of either 2 scripts (a bash script to run ssh, combined with the python script to return the arguments) or alternatively human intervention to type the bash command directly as formatted above.
Question:
Is there a way, only using python, to start/fork an interactive service (like ssh), by using subprocess or some comparable module, and have this forked child process remain alive in the foreground, even after its parent (python) has sys.exit()'d?
Considerations:
In this case, the point of this question is not to script the submission of ssh credentials to ssh from within Python. It is how to spawn a subprocess which continues to run foregrounded after its parent/spawner terminates.
EDIT:
The following resources are related:
Run a program from python, and have it continue to run after the script is killed
how to spawn new independent process in python
Indefinite daemonized process spawning in Python
Python spawn off a child subprocess, detach, and exit
I think you want to "exec". Like this:
import resolve_ip
import os
host = resolve_ip.get_host_to_use() # you figure this part out
os.execlp('ssh', 'ssh', host)
That will replace the Python interpreter process image with the ssh process image, and keep running. So you will end up as if you had run ssh instead of Python, and the interpreter will no longer execute at all.
Related
I want to call shell script from python code. The shell script which I am trying to call is having multiple database (DB2) call in it; means it connects to DB2 database multiple times and execute different database sqls. I tried using subprocess.call method like (subprocess.call(['./<shell script with full path>'])); but it seems before the script connects to database and executes the commands mentioned within the script, it is terminating. But when I am calling the shell script as a standalone script from command line, then it is working good.
Is there any other way this can be handled?
subprocess: The subprocess module allows you to spawn new processes,
connect to their input/output/error pipes, and obtain their return
codes.
http://docs.python.org/library/subprocess.html
Usage:
import subprocess
process = subprocess.Popen(command, shell=True)
process.wait()
print process.returncode
Side note: It is best practice to avoid using shell=True as it is a security hazard.
Actual meaning of 'shell=True' in subprocess
My question is how does a shell script execute another shell script does it spawn in a new process? or is it executed in the same process as the script that called it? A example would be a Python script that is executed from a shell script after a condition is met also how would someone write this shell script where it would spawn the Python script and then exit itself without killing the Python script
Yes shell also will spawn new process if you invoke shell script within shell.
if you want to spawn python script and exit without killing, run python in background in shell script/ or disown python process.
Python can spawn new processes and control their lives.
You can create and manage them using modules such as subprocess: "The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes."
If you want to run them on other threads, you can use multiprocessing: "multiprocessing is a package that supports spawning processes using an API similar to the threading module."
Shell scripts are something different, maybe this question (and its answers) can help you understand shell scripts launching other scripts :)
I am making a python program, lets say A. Which is used to monitor python script B
When the python program shuts down, there is an exit function that as registered via atexit.register(), to do some clean up it need to re-run python script B, which need to stay running even when python script A has shutdown.
Python Script B can't be part of Python Script A.
What do I need to do to make that happen, I have already tried a few things like using subprocess.Popen(programBCommand), but that doesn't seem to work as it prevents A from shutting down.
I am using a Debian Operating System
If script B needs to be launched by script A, and continue running whether or not A completes (and not prevent A from exiting), you're looking at writing a UNIX daemon process. The easiest way to do this is to use the python-daemon module to make script B daemonize itself without a lot of explicit mucking about with the details of changing the working directory, detaching from the parent, etc.
Note: The process of daemonizing, UNIX-style, detaches from the process that launched it, so you couldn't directly monitor script B from script A through the Popen object (it would appear to exit immediately). You'd need to arrange some other form of tracking, e.g. identifying or communicating the pid of the daemonized process to script A by some indirect method.
I'm trying use python's cmd library to create a shell with limited commands. One requirement I have is to be able to run a command that executes an existing shell script which opens an ssh session on a remote machine and from there allows the user to interact with the remote shell as if it was a regular ssh session.
Simply using subprocess.Popen('[/path/to/connect.sh]') works well at least as a starting point except for one issue. You can interact with the remote shell but the input that you type is not shown on stdout...so for example you see the prompt on your stdout but when you type 'ls' you don't see it being typed but when you hit return it works as expected.
I'm trying to wrap my head around how to print the input to stdout and still send it along to the remote ssh session.
EDIT:
Actual code without using cmd was just the one line:
ssh_session = subprocess.Popen(['connect.sh'])
it was fired from a do_* method in a class which extended cmd.Cmd. I think I may end up using paramiko but would still be interested in anyone's input on this.
Assuming you are using a Unix like system, SSH detects if you are on a terminal or not. When it detects that you are not on a terminal, like when using subprocess, it will not echo the characters typed. Instead you might want to use a pseudo-terminal, see pexpect, or pty. This way you can get the output from SSH as if it was running on a true terminal.
I have what I believe to be a fairly unique problem for a script I use to stand up webservers on remote machines.
I have a controller script which after checking a ledger initiates a "builder" script on a remote machine. Part of this builder script calls a bash script which starts a process I want to continue running after both scripts are finished.
My only problem is that the builder script seems to finish (gets to the last line) but doesn't seem to return control to the controller script.
For the record I am using subprocess.call in the controller script (to initiate a ssh call) to start the builder script on the remote machine. I have toyed with various ways of initiating the bash script in the builder script but it seems the builder won't return control to the controller until kill the processes spawned by the bash script.
Things I have tried:
pid=os.spawnl(os.P_NOWAIT,dest+'/start_background_script.sh')
pid=subprocess.Popen([dest+'/start_background_script.sh'])
os.system(dest+'/start_background_script.sh &')
pid=os.spawnl(os.P_NOWAIT,dest+'/start_background_script.sh')
The bash script is written to that you execute it and it backgrounds two processes and then returns control.
Any recommendations?
Sound like a job for fabric to me.
Fabric wraps the handling of shell-calls on remote (and also local) machines for you.