I am writing a Python3 script, which must run this system command on my Ubuntu 20.04.5 LTS machine:
sudo su - otherUser -c "scp -P 1234 otherUser@10.10.10.10:/path/to/file/x.txt /tmp/x.txt"
When I manually paste this command into the server's command line, the command works just fine. Now I need my Python script to execute it. Thanks to posts like this, I believe that the subprocess.run()
command should work here.
Here's my test code:
import subprocess
def main():
subprocess.run(["ls", "-l"]) # For testing purposes
print("===================================================================================")
cmd = ["sudo", "su - otherUser", "-c", "\"scp -P 1234 otherUser@10.10.10.10:/path/to/file/x.txt /tmp/x.txt\""]
print(cmd) # see the command first
subprocess.run(cmd)
if __name__ == "__main__":
main()
Output is:
me@ubuntu01$ python3 testSubprocess.py
total 4
-rw-r----- 1 demo demo 576 Jan 18 21:08 testSubprocess.py
===================================================================================
['sudo', 'su - otherUser', '-c', '"scp -P 1234 otherUser@10.10.10.10:/path/to/file/x.txt /tmp/x.txt"']
sudo: su - otherUser: command not found
me@ubuntu01$
As you can tell, I'm really confused about how to parse the command so that subprocess.run()
can understand it. The documentation (here and here) isn't that helpful for a beginner like me. The format of subprocess.run()
is:
subprocess.run(args, *, ...lots of other stuff...)
...where args
is:
args is required for all calls and should be a string, or a sequence of program arguments. Providing a sequence of arguments is generally preferred, as it allows the module to take care of any required escaping and quoting of arguments (e.g. to permit spaces in file names). If passing a single string, either shell must be True (see below) or else the string must simply name the program to be executed without specifying any arguments.
I don't fully follow that, but I do understand that subprocess.run()
will take a list of strings that should be the command-to-be-executed. Okay. Can someone explain how to slice up my original command?