3

I want to use Python to run the cp command on Linux, thus copying a file. I have this code:

newfile = "namePart1" + dictionary[key] + "namePart2"

os.system("cp cfn5e10_1.lp newfile")

How can I make it so that the text newfile on the second line is replaced with the newfile variable that I calculated on the previous line?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
user1002288
  • 4,860
  • 10
  • 50
  • 78
  • 1
    Are you sure you're calling os.system like that? Because it's going to copy the original file to a file named "newfile" (not to whatever it says in the variable newfile) – Savir Jul 20 '12 at 17:56
  • 2
    It would be much better to ask what the best way to copy or rename files is in Python, rather than asking how to use `cp` or `mv` from Python. – Charles Duffy Jul 20 '12 at 18:44
  • As asked, the question made no sense to ask: the apparent problem was that `"cp cfn5e10_1.lp newfile"` contains the actual text `newfile` instead of the contents of the `newfile` variable. However, OP **demonstrably already knew how to solve that problem** - since the previous line of code reads `newfile = "namePart1" + dictionary[key] + "namePart2"`, not `newfile = "namePart1 dictionary[key] namePart2"`, and there is no question about how to substitute in that value. As such, it should have been closed as a typo (or "too localized", in 2012-speak). – Karl Knechtel Nov 26 '22 at 10:08
  • Considering the question in hindsight, there are two ways to make sense of it: either we can ignore the issue with the setup, and take it as a serious question about string interpolation; or we can ignore the issue with OP trying an inappropriate approach to the problem, and take it as a serious question about file copying. However, **both of these are extremely common duplicates with much better versions available**; thus I have closed this as a duplicate of both, and propose that it should be deleted - there is no value added here. – Karl Knechtel Nov 26 '22 at 10:10
  • I suppose, going off the title alone, that we could instead just take this as a question about how to run OS commands from Python. But OP already knew the basic syntax for this, and there are better duplicates for that, too. – Karl Knechtel Nov 26 '22 at 10:11

3 Answers3

13

Use shutil.copyfile to copy a file instead of os.sytem, it doesn't need to create a new process and it will automatically handle filenames with unusual characters in them, e.g. spaces -- os.system just passes the command to the shell, and the shell might break up filenames that have spaces in them, among other possible issues.

For example:

newfile = "namePart1" + dictionary[key] + "namePart2"
shutil.copyfile("cfn5e10_1.lp", newfile)
Adam Rosenfield
  • 390,455
  • 97
  • 512
  • 589
  • This will unfortunately not work on all filestypes. For example a formatted xls will not retain its formatting when using `copyfile`. For OP though, it should do the job. – Red-Tune-84 Jul 02 '17 at 18:18
  • @Kazanz: Umm, what? What do formatted Excel documents have to do with anything? Can you be more specific? `shutil.copyfile` very likely won't copy a file's [alternate data streams](https://en.wikipedia.org/wiki/NTFS#Alternate_data_streams_.28ADS.29) if present, but I'm not aware of any usage of alternate data streams by Excel files. – Adam Rosenfield Jul 10 '17 at 03:48
  • Yes, you are correct. `shutil.copyfile` is the solution, OP should just be aware of the caveat that it will not copy file metadata. [See warning here](https://docs.python.org/3.6/library/shutil.html#module-shutil). "On POSIX platforms, this means that file owner and group are lost as well as ACLs. On Mac OS, the resource fork and other metadata are not used. This means that resources will be lost and file type and creator codes will not be correct. On Windows, file owners, ACLs and alternate data streams are not copied" - python docs – Red-Tune-84 Jul 10 '17 at 15:46
4

This will not replace newfile with your variable.

os.system("cp cfn5e10_1.lp newfile")

You need to concatenate the variable to the end of the string like so:

os.system("cp cfn5e10_1.lp " + newfile)
Daniel Li
  • 14,976
  • 6
  • 43
  • 60
2

If you want to call cp from Python, use the subprocess module:

subprocess.call(["cp", "cfn5e10_1.lp", "newfile"])

But it's better to use a function from the shutil module instead.

MRAB
  • 20,356
  • 6
  • 40
  • 33