How to call multiple bash functions using | in python

I am using scientific software (called vasp) that only works in bash, and using Python to create a script that will make several starts for me. When I use subprocess.check_call to call the function normally, it works fine, but when I add '| tee tee_output 'does not work.

subprocess.check_call('vasp') #this works subprocess.check_call('vasp | tee tee_output') #this doesn't 

I actually write in python and program in general.

+4
source share
4 answers

Try it. It executes a command (passed as a string) through the shell instead of executing the command directly. (This is the equivalent of calling the shell itself with the -c flag, ie Popen(['/bin/sh', '-c', args[0], args[1], ...]) ):

 subprocess.check_call('vasp | tee tee_output', shell=True) 

Note the warning in the docs about this method.

+4
source

You can do it:

 vasp = subprocess.Popen('vasp', stdout=subprocess.PIPE) subprocess.check_call(('tee', 'tee_output'), stdin=vasp.stdout) 

This is usually safer than using shell=True , especially if you cannot trust the input.

Note that check_call checks the return code tee , not vasp , to see if it should raise a CalledProcessError . (The shell=True method will do the same, since it matches the behavior of the shell shell.) If you want, you can check the vasp return vasp yourself by calling vasp.poll() . (Another method will not allow you to do this.)

+2
source

Do not use shell = True, it has many security holes. Instead, do something like this

 cmd1 = ['vasp'] cmd2 = ['tee', 'tee_output'] runcmd = subprocess.Popen(cmd1, stdout=subprocess.PIPE) runcmd2 = subprocess.Popen(cmd2, stdin=runcmd.stdout, stdout=subprocess.PIPE) runcmd2.communicate() 

I know him longer, but much safer.

+2
source

Further information can be found in the documentation: http://docs.python.org/library/pipes.html

Just add more lines to the t object

0
source

Source: https://habr.com/ru/post/1400285/


All Articles