How to launch a python shell with subprocess.run - python

I have a function in my python script that needs to load a python shell.
run('python /my/script', shell=True)
The problem is that when I type something, the bash shell is providing output instead of the python shell.
Do you know why and how can I fix it?

You should use the subrocess Python module. If path of your Python executable is set as environment variable, you need to write only python when you call the another Python file, in other case you need the write the full path of your Python executable.
test.py Python file:
import subprocess
process = subprocess.Popen(["python", "other.py"], stderr=subprocess.PIPE, stdout=subprocess.PIPE)
std_out, std_err = process.communicate()
print(std_out)
other.py Python file:
print("Hello from other Python file.")
output of test.py Python file:
>>>python test.py
Hello from other Python file.

Related

How can I execute commands through python in terminal MAC?

When I manually run this command in Terminal, it executes, but through Python it gives the error that the directory is not available in Python packages.
I am using the following command
source ~/trytry/shell.sh
This is my test shell file:
#!/bin/sh
echo hello
when I executed " source ~/test.sh ", it will print hello at console.
This is my python code:
>>> import commands
>>> commands.getstatusoutput("source ~/test.sh")
(0, 'hello')
It works without any problem. So, would you please show your code?
What it looks like to me is that you have a shell script, and not a python file which would have the .py extension instead of .sh. The error may have to do with the fact that it isn't a python file you're trying to run.

python: how to run a program with a command line call (that takes a user's keystroke as input) from within another program?

I can run one program by typing: python enable_robot.py -e in the command line, but I want to run it from within another program.
In the other program, I imported subprocess and had subprocess.Popen(['enable_robot', 'baxter_tools/scripts/enable_robot.py','-e']), but I get an error message saying something about a callback.
If I comment out this line, the rest of my program works perfectly fine.
Any suggestions on how I could change this line to get my code to work or if I shouldn't be using subprocess at all?
If enable_robot.py requires user input, probably it wasn't meant to run from another python script. you might want to import it as a module: import enable_robot and run the functions you want to use from there.
If you want to stick to the subprocess, you can pass input with communicate:
p = subprocess.Popen(['enable_robot', 'baxter_tools/scripts/enable_robot.py','-e'])
p.communicate(input=b'whatever string\nnext line')
communicate documentation, example.
Your program enable_robot.py should meet the following requirements:
The first line is a path indicating what program is used to interpret
the script. In this case, it is the python path.
Your script should be executable
A very simple example. We have two python scripts: called.py and caller.py
Usage: caller.py will execute called.py using subprocess.Popen()
File /tmp/called.py
#!/usr/bin/python
print("OK")
File /tmp/caller.py
#!/usr/bin/python
import subprocess
proc = subprocess.Popen(['/tmp/called.py'])
Make both executable:
chmod +x /tmp/caller.py
chmod +x /tmp/called.py
caller.py output:
$ /tmp/caller.py
$ OK

Launch python script with abaqus command

I have a command file (.cmd) which I use to launch Abaqus command line windows.
Then, I use the command 'abaqus python test.py' to launch python command inside Abaqus.
Now, I would like to use a python script to do that.
I try something like this but doesn't work. Someone know the trick ?
Thanks !!
import subprocess
AbaqusPath=r"C:\Abaqus\script\abaqus.cmd"
args= AbaqusPath + "-abaqus python test.py"
subprocess.call(args)
Using .cmd-file:
This way might work with cmd file:
abaqusPath = "C:\\Abaqus\\script\\abaqus.cmd /C"
args = AbaqusPath + "abaqus python test.py"
subprocess.call(args)
Flag /C is needed to run command and then terminate.
Easiest way:
Just add the folder with abaqus commands (typical path C:\Abaqus\Commands) into the PATH variable of the system. This will give the access to commands like abaqus, abq6141 etc. in cmd directly.
When just use the following in your script:
subprocess.call("abaqus python test.py")
Using .bat-file:
If the configuration of PATH variable is impossible and the first way does not work, .bat-files from abaqus can be used as follows:
abaqusPath = "C:\\Abaqus\\Commands\\abaqus.bat "
args = AbaqusPath + "python test.py"
subprocess.call(args)
I've never had any success using just string arguments for subprocess functions.
I would try it this way:
import subprocess
abaqus_path = r"C:\Abaqus\script\abaqus.cmd"
subprocess.call([abaqus_path, '-abaqus', 'python', 'test.py'])

Standard input inconsistency between command line and subprocess.call

I would like to create a file that will be used as standard input for a python script, and invoke said script with subprocess.call.
When I do it directly in the command line it works fine:
The input file:
# test_input
1/2/3
The python script
# script.py
thisDate = input('Please enter date: ').rstrip()
The following command works just fine:
python script.py < test_input
But when I try to do the following from within another python script, it doesn't work. (from this)
outfile1 = open('test_input', 'w')
outfile1.write('1/2/3')
outfile1.close()
input1 = open('test_input')
subprocess.call(['python', 'script.py'], stdin=input1)
But then I get the following error:
>>>thisDate = input('Please enter date: ').rstrip()
>>>AttributeError: 'int' object has no attribute 'rstrip'
When I did some debugging, it seems that it is getting the integer 0 as the input.
What is causing the inconsistency here? Are the two methods not equivalent (evidently they are not, but why)? My ultimate goal is to perform the exact same task as the above command line version that worked.
Thank you
You are using input when it should be raw_input, input in python2 will eval the string. If you run the script with python3 it will work as is, for python2 change to raw_input.
Using check_call is usually a better approach and using with to open your files.
import subprocess
with open('test_input') as input1:
subprocess.check_call(['python3', 'script.py'], stdin=input1)
So chepner was correct. When I amended the following line:
subprocess.call(['python', 'script.py'], stdin=input1)
to:
subprocess.call(['python3', 'script.py'], stdin=input1)
it worked just fine.
(I am trying to do this in python3)
In the first instance, the file has two lines, and input() reads and parses the first line, which is a comment.
In the second case, the comment line is missing, so Python reads and parses a number.
You probably meant to use raw_input(), or run the script with Python 3.
(You probably also meant for the input file to end with a newline, and it doesn't really make sense to use subprocess.call() to run Python when you are already running Python.)
python script.py < test_input command should fail. You might mean: python3 script.py < test_input instead due to the difference between input() vs raw_input() on Python 2 as mentioned in other answers. python as a rule refers to Python 2 version.
if the parent script is run only using python3 then you could use sys.executable to run the child script using the same python version (the same executable):
#!/usr/bin/env python3
import subprocess
import sys
with open('test_input', 'rb', 0) as input_file:
subprocess.check_call([sys.executable or 'python3', 'script.py'],
stdin=input_file)
If the parent and the child may use different python versions then set the correct shebang in script.py e.g., #!/usr/bin/env python3 and run the script directly:
#!/usr/bin/env python
import subprocess
with open('test_input', 'rb', 0) as input_file:
subprocess.check_call(['./script.py'], stdin=input_file)
Here, the child script may choose its own python version. Make sure the script has executable permissions: chmod +x script.py. Note: Python Launcher for Windows understands the shebang syntax too.
Unrelated: use .communicate() instead of outfile1.write('1/2/3'):
#!/usr/bin/env python3
from subprocess import Popen, PIPE
with Popen(['./script.py'], stdin=PIPE, universal_newlines=True) as p:
p.communicate('1/2/3')

Execute /bin script from other python script

I have a script in my project's bin directory, and I want to execute it from a cron. Both scripts are written in python.
Target file :
App_directory/bin/script_name
Want to execute script_name script with some parameters from App_directory/cron/script_name1.py
How do I achieve that ?
Try:
import os
os.system('/path/to/App_directory/bin/script_name')
Or if script_name is not executable and/or doesn't have the shabang (#!/usr/bin/env python):
import os
os.system('python /path/to/App_directory/bin/script_name')
The subprocess module is much better than using os.system. Just do:
import subprocess
subprocess.call(['/path/to/App_directory/bin/script_name'])
The subprocess.call function returns the returncode (exit status) of the script.
It works for me...
import subprocess
process = subprocess.Popen('script_name')
print process.communicate()

Categories

Resources