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 :)
Related
I have an embedded linux system that I need to run a python script whenever it boots. The python script needs to have a terminal interface so the user can interact and see outputs. The script also spawns another process to transfer large amounts of data over SPI, this was written in C.
I've managed to get the script to start on launch and have terminal access by adding
#reboot /usr/bin/screen -d -m python3 /scripts/my_script.py
to the crontab. I can then do "screen -r" and interact with the script. However if launched in this way the script fails to start the external SPI script. In python I launch the script with subprocess.Popen
proc=subprocess.Popen(["./spi_newpins,"-o","/media/SD/"+ latest_file"])
and this works perfectly whenever I manually launch the script, even within screen. Just not when it is launched by crontab. Does anyone have any ideas on how to get the spi subprocess to also work from crontab?
Fixed now, I had to add an absolute path to the spi_newpins function call
proc=subprocess.Popen(["/scripts/./spi_newpins","-o","/media/SD/"+ latest_file"])
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
Normally, I would use "blender -P script.py" to run a python script. In this case, a new blender process is started to execute the script. What I am trying to do now is to run a script using a blender process that is already running, instead of starting a new one.
I have not seen any source on this issue so far, which makes me concern about the actual feasibility of this approach.
Any help would be appreciated.
Blender isn't designed to be started from the cli and to then keep receiving more commands from the cli as it is running. It does however include a text editor that can open text files and run the text block as a python script, it also includes a python console that can be used to interactively type in commands while blender is running. You may also find this addon useful as it lets you to run a text block in the python console, this leaves you with an interactive session that contains the variables as they exist at the end of the scripts execution.
There is a cli option to run blender as a python console blender --python-console - the gui does not get updated while this console is running, so you could open and exec several scripts and then when you exit the console, blender will update it's gui and allow interactive use, or if you start in background mode -b then it will quit when you exit the console.
My solution was to launch Blender via console with a python script (blender --python script.py) that contains a while loop and creates a server socket to receive requests to process some specific code. The loop will prevent blender from opening the GUI, and the socket will handle the multiple requests inside the same blender process.
I am trying to use os.system (soon to be replaced with subprocess) to call a shell script (which runs a process as a daemon)
os.system('/path/to/shell_script.sh')
The shell script looks like:
nohup /path/to/program &
If I execute this shell script in my local environment, I have to hit enter before being returned to the console as the shell script is running a process as a daemon. If I do the above command in python, I also have to hit enter before being returned to the console.
However, if I do this in a python program, it just hangs forever.
How can I get the python program to resume execution after calling a shell script that runs a process as a daemon?
From here -
Within a script, running a command in the background with an ampersand (&)
may cause the script to hang until ENTER is hit. This seems to occur with
commands that write to stdout.
You should try redirecting your output to some file (or null if you do not need it), maybe /dev/null , if you really do not need the output.
nohup /path/to/program > /dev/null &
Why don't you trying using a separate thread?
Wrap up your process into something like
def run(my_arg):
my_process(my_arg)
thread = Thread(target = run, args = (my_arg, ))
thread.start()
Checkout join and lock for more control over the thread execution.
https://docs.python.org/2/library/threading.html
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.