The Subprocess.run Method
The Subprocess.run method takes a list of arguments. When the method is called, it executes the command and waits for the process to finish, returning a “CompletedProcess” object in the end. The “CompletedProcess” object returns stdout, stderr, original arguments used while calling the method, and a return code. Stdout refers to the data stream produced by the command, while stderr refers to any errors raised during execution of the program. Any non-zero return code (exit code) would mean error with the command executed in the subprocess.run method.
Example 1: Output Contents of A Text File Using the Subprocess.run Method
The command below will output the contents of a “data.txt” file, assuming that it contains a “name=John” string.
subprocess.run(["cat", "data.txt"])
Running the code above will return the following output:
CompletedProcess(args=['cat', 'data.txt'], returncode=0)
The first element of the list argument is the name of the command to be executed. Any element in the list that follows the first element are considered command-line options or switches. You can use single dash and double dashes, as well, to define the options. For example, to list files and folders in a directory, the code would be “subprocess.run([“ls”, “-l”]”. In most of these cases, you can consider any space-separated argument in a shell command as an individual element in the list supplied to the subprocess.run method.
Example 2: Suppress Output of Subprocess.run Method
To suppress the output of the subprocess.run method, you will have to supply “stdout=subprocess.DEVNULL” and “stderr=subprocess.DEVNULL” as additional arguments.
subprocess.run(["cat", "data.txt"], stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
Running the code above will produce the following output:
Example 3: Capture Output of Subprocess.run Method
To capture the output of the subprocess.run method, use an additional argument named “capture_output=True”.
output = subprocess.run(["cat", "data.txt"], capture_output=True)
print (output)
Running the code above will produce the following output:
stdout=b'name=John\n', stderr=b'')
You can individually access stdout and stderr values by using “output.stdout” and “output.stderr” methods. The output is produced as a byte sequence. To get a string as output, use “output.stdout.decode(“utf-8”)” method. You can also supply “text=True” as an extra argument to the subprocess.run call to get the output in string format. To get exit status code, you can use the “output.returncode” method.
Example 4: Raise Exception on Failure of Command Executed by Subprocess.run Method
To raise an exception when the command exits with a non-zero status, use the “check=True” argument.
subprocess.run(["cat", "data.tx"], capture_output=True, text=True, check=True)
Running the code above will produce the following output:
subprocess.CalledProcessError: Command '['cat', 'data.tx']'
returned non-zero exit status 1.
Example 5: Pass a String to Command Executed by the Subprocess.run Method
You can pass a string to the command to be executed by subprocess.run method by using “input=’string’” argument.
output = subprocess.run(["cat"], input="data.txt", capture_output=True,
text=True, check=True)
print (output)
Running the code above will produce the following output:
As you can see, the code above passes “data.txt” as a string and not as a file object. To pass “data.txt” as a file, use the “stdin” argument.
output = subprocess.run(["cat"], stdin=f, capture_output=True,
text=True, check=True)
print (output)
Running the code above will produce the following output:
Example 6: Execute Command Directly in Shell Using the Subprocess.run Method
It is possible to run a command directly into a shell “as is,” instead of using a string split in the main command and the options that follow it. To do this, you must pass “shell=True” as an additional argument. This is however, discouraged by python developers as using “shell=True” can lead to security issues. You can read more about security implications from here.
subprocess.run("cat 'data.txt’", shell=True)
Running the code above will produce the following output:
Conclusion
The subprocess.run method in Python is pretty powerful, as it allows you to run shell commands within python itself. This helps in limiting all code to python itself without the need to have additional shell script code in separate files. It can be, however, quite tricky to correctly tokenize shell commands in a python list. You can use the “shlex.split()” method to tokenize simple shell commands, but in long, complex commands – especially those with pipe symbols – shlex fails to correctly split the command. In such cases, debugging can be a tricky issue. You can use the “shell=True” argument to avoid this, but there are certain security concerns associated with this action.
from Linux Hint https://ift.tt/3diWnQg
0 Comments