Why does the below MWE not redirect output to /dev/null.
#!/usr/bin/env python
import os
if __name__ == "__main__":
os.system ( 'echo hello &>/dev/null' )
Not sure, but another (better) way to do it is:
from os import devnull
from subprocess import call
if __name__ == "__main__":
with open(devnull, 'w') as dn:
call(['echo', 'hello'], stdout=dn, stderr=dn)
This opens /dev/null for writing, and redirects output of the spawned process to there.
UPDATE based on comments from #abarnert
In the specific case of echo, to get identically the same behavior you will want to use shell=True because otherwise it will call /bin/echo, not the shell builtin:
call('echo hello', shell=True, stdout=dn, stderr=dn)
Also, on Python 3.3+, you can do
from subprocess import call, DEVNULL
if __name__ == "__main__":
call('echo hello', shell=True, stdout=DEVNULL, stderr=DEVNULL)
Related
How can I get string as return in this script?
main.py
from subprocess import Popen, PIPE
import os
import sys
child = os.path.join(os.path.dirname(__file__), "child.py")
command = [sys.executable, child, "test"]
process = Popen(command, stdout=PIPE, stdin=PIPE)
process.communicate()
print(process.poll())
child.py
import sys
def main(i):
return i*3
if __name__ == '__main__':
main(*sys.argv[1:])
I get only 0.
I think get response from print() and process.communicate() not the best way.
Processes can't return values in the same sense a function can.
They can only set an exit code (which is the 0 you get).
You can, however, use stdin and stdout to communicate between the main script and child.py.
To "return" something from a child, just print the value you want to return.
# child.py
print("Hello from child")
The parent would do something like this:
process = Popen(command, stdout=PIPE, stdin=PIPE)
stdout, stderr = Popen.communicate()
assert stdout == "Hello from child"
I am trying to create a new process to run another python file using the following code.
proc = subprocess.Popen(["python test.py"],shell=True)#,stdout=DEVNULL, stderr=STDOUT
proc.wait()
It works on window but when I tried in an ubuntu console. It would trigger the python console/interpreter instead of running the python file.
Any help would be appreciated
As i commented the previews answer, do not use shell=True if you don't need it, please refer to python doc, there are serious security implication using this option.
working example:
╭─root#debi /tmp
╰─# cat 1.py
def main():
print("ok")
if __name__ == '__main__':
main()
╭─root#debi /tmp
╰─# cat 2.py
import subprocess
def main():
proc = subprocess.Popen(["python", "1.py"])
proc.wait()
if __name__ == '__main__':
main()
╭─root#debi /tmp
╰─# python3 2.py
ok
╭─root#debi /tmp
╰─#
You have to separate arguments python and test.py for the things to work properly:
proc = subprocess.Popen(["python", "test.py"],shell=True)
proc.wait()
I have created a simple echo.py like this:
import sys
while True:
s = sys.stdin.readline()
s = s.strip('\n')
if s == 'exit':
break
sys.stdout.write("You typed: %s\n" % s)
It works well on the terminal.
And another program to interact with echo.py named main.py
import subprocess
if __name__ == '__main__':
proc = subprocess.Popen(['python', 'echo.py'],stdin=subprocess.PIPE,
stdout=subprocess.PIPE,stderr=subprocess.PIPE)
proc.stdin.write(b'Hello\n')
proc.stdin.flush()
print(proc.stdout.readline())
proc.stdin.write(b'Hello World\n')
proc.stdin.flush()
print(proc.stdout.readline())
proc.terminate()
The main.py just hangs forever.
The thing is if I create subprocess with ['python', '-i'], it works.
Add sys.stdout.flush() to echo.py. Buffering works differently if you run the process with Popen instead of the terminal.
I believe the problem is the while loop.. You're opening a subprocess, writing to it and flushing, and it does all that, but never finishes readline() because of the loop.
I'm the Python beginner and I have a task to do. I have to write a function, that opens a program (.bin), execute it so I can see the results. This program requires 2 arguments from command line. I used os.spawnv, but it doesn't work...
#!/usr/bin/python
import sys
import os
def calculate_chi():
if len(sys.argv)>1:
pdb_name=sys.argv[1]
dat_name=sys.argv[2]
crysol='/usr/bin/crysol'
os.spawnv(os.P_NOWAIT,crysol,[crysol,pdb_name,dat_name])
def main():
calculate_chi()
Can you help me?
You can use python subprocess module:
import subprocess
proc = subprocess.Popen(['/usr/bin/crysol', sys.argv[1], sys.argv[2]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while proc.poll() is None:
out = proc.stdout.readline() #read crystol's output from stdout and stderr
print out
retunValue = proc.wait() #wait for subprocess to return and get the return value
Use subprocess. It was intended to replace spawn.
import subprocess
subprocess.call([crysol, pdb_name, dat_name])
Everyone uses subprocess.Popen these days. An example call to your process would be
process = Popen(["/usr/bin/crysol", pdb_name, dat_name],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Im executing a module popen1.py and that calls popen2.py using the subprocess module,
but the output of popen2.py is not being displayed..When I display the child process id , its being displayed..Where does the output will be printed for popen2.py
call
child = subprocess.Popen(['python', 'popen2.py',"parm1='test'","parm='test1'"], shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
After the process completes, you can read child.stdout and child.stderr to get the data (since you pass subprocess.PIPE)
Alternatively, you can use oudata,errdata = child.communicate() which will wait for the subprocess to finish and then give you it's output as strings.
From a design perspective, it's better to import. I would refactor popen2.py as follows:
#popen2.py
# ... stuff here
def run(*argv):
#...
if __name__ == '__main__':
import sys
run(sys.argv[1:])
Then you can just import and run popen2.py in popen1.py:
#popen1.py
import popen2
popen2.run("parm1=test","parm=test1")
You can use child.stdout/child.stdin to comunicate with the process:
child = subprocess.Popen(['python', 'popen2.py',"parm1='test'","parm='test1'"], shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print child.stdout.readlines()