For some reasons, I need to move from os.system
to subprocess.run
to concatenate files (can be ASCII files but also binary ones).
While it works fine under Windows (anaconda), the following snippet seems blocked or waiting for something under Linux (Ubuntu): what am I missing?
Note a.txt
and b.txt
just contain a single (ascii) word.
import os, subprocess
Path = os.getcwd()
bottomFile = 'b.txt'
topFile = 'a.txt'
resultFile = 'c.txt'
command_line = f"cat {Path}/{topFile} {Path}/{bottomFile} > {Path}/{resultFile}"
args = command_line.split()
subprocess.run(args, shell = True)
2
Answers
When you use
subprocess.run()
withshell=True
, the argument should be a single string with the full command line, which then gets interpreted by the shell.Simply change your
run()
call to this and it all works on both Linux and Windows:It’s when you call
run()
withshell=False
that you need to split the command line into the program and its arguments.Relevant Documentation
Ref: https://docs.python.org/3/library/subprocess.html
Search for
shell=True
on the page: undersubprocess.Popen
(whichrun()
calls) there is a description of what that does, and how it differs between Windows and Linux.A more efficient and much more secure version of your code would instead look like:
Unlike the version with
shell=True
, this works even if your path or filenames have spaces, and a filename that contains something like$(rm -rf ~)
in it won’t cause your home directory to be deleted.