#Subprocess Module
#The subprocess module is used to run new applications or programs through Python code by creating new processes. It also helps to obtain the input/output/error pipes as well as the exit codes of various commands.
import subprocess
#it will run ls command and will print the output
subprocess.run('ls')
#To use the suboptions of command you need to pass shell=True parameter also in subprocess.run
subprocess.run('ls -la',shell=True)
#If you don't want to pass shell=True, you can pass it a list of arguments
subprocess.run(['ls','-la'])
#this will print the command output in screen and will store CompletedProcess(args=['ls', '-la'], returncode=0)
p = subprocess.run(['ls','-la'])
#we can check arguments and return code, 0 meaning run with 0 errors
print(p.args)
print(p.returncode)
#To store the standoutput and error in variable use capture_output=True
p = subprocess.run(['ls', '/home/kushagra/Desktop/udemy'],capture_output=True)
print(p)
#if only want stdout without args and returncode
print(p.stdout)
#we can decode this by using decode
# it will print the output same as linux command would have done
print(p.stdout.decode())
#another way is that instead of using decode we can use
p = subprocess.run(['ls','/home/kushagra/Desktop/udemy'],capture_output=True,text=True)
print(p.stdout)
#To store Standard Output and not error
p = subprocess.run(['ls','/home/kushagra/Desktop/udemy'],stdout=subprocess.PIPE,text=True)
#will result as above
print(p.stdout)
#we can also pipe the out to file. [can be used for logging purposes]
with open('output.txt','w') as f:
p = subprocess.run(['ls','/home/kushagra/Desktop/udemy'],stdout=f,text=True)
#we can see that the output of the command is now saved in the file.
!cat output.txt
#listing the contents of file that doesnot exist.
p = subprocess.run(['ls','-la','den'],capture_output=True,text=True)
#will give the returncode if not 0 means error
print(p.returncode)
#for checking the error
print(p.stderr)
#python won't throw exception if external command fails.. if you want python to do that you can pass check=True parameter in subprocess.run
p = subprocess.run(['ls','den'],capture_output=True,check=True,text=True)
#we can see now python throws the exception which might be useful in some case.
#we can redirect out standard error to /dev/null if you don't wish to see any error message
p = subprocess.run(['ls','den'],stderr=subprocess.DEVNULL)
#we can see no error here.
print(p.stderr)
#case when we want to transfer output of one command to input of another. [output redirection]
p1 = subprocess.run(['cat','yo.txt'],capture_output=True,text=True)
#contents of file
print(p1.stdout)
#using the output of p1 in p2
p2= subprocess.run(['grep','-n','test'],capture_output=True,text=True,input=p1.stdout)
#printing result of grep command
print(p2.stdout)
#or we can directly use this we are not going to use parsing between commands anywhere else.
p1 = subprocess.run('cat yo.txt | grep -n test',capture_output=True,text=True,shell=True)
print(p1.stdout)