1

I want to remove all the files and directories except for some of them by using

`subprocess.call(['rm','-r','!(new_models|creat_model.py|my_mos.tit)'])`

but it gives back information

rm: cannot remove `!(new_models|creat_model.py|my_mos.tit)': No such file or directory

how can I fix this? Thanks

4
  • 2
    Do you have a file or a directory named !(new_models|creat_model.py|my_mos.tit)?
    – wap26
    Commented Jul 10, 2014 at 7:25
  • in bash I think this means the files i don't want to remove
    – simon_tum
    Commented Jul 10, 2014 at 7:30
  • 3
    You're right, but with your python line, you don't run a bash to interpret this syntax ; you directly create a process running the rm program.
    – wap26
    Commented Jul 10, 2014 at 7:31
  • ok, and how can I fix this?
    – simon_tum
    Commented Jul 10, 2014 at 7:35

3 Answers 3

6

If you use that rm command on the command line the !(…|…|…) pattern is expanded by the shell into all file names except those in the pattern before calling rm. Your code calls rm directly so rm gets the shell pattern as a file name and tries to delete a file with that name.

You have to add shell=True to the argument list of subprocess.call() or actually code this in Python instead of calling external commands. Downside: That would be more than one line. Upside: it can be done independently from external shells and system dependent external programs.

2

An alternative to shell=True could be the usage of glob and manual filtering:

import glob
files = [i for i in glob.glob("*") if i not in ('new_models', 'creat_model.py', 'my_mos.tit')]
subprocess.call(['rm','-r'] + files)

Edit 4 years later:

Without glob (of which I don't remember why I suggested it):

import os
files = [i for i in os.listdir() if i not in ('new_models', 'creat_model.py', 'my_mos.tit')]
subprocess.call(['rm','-r'] + files)
2
  • I don't see the reason for glob() here when you don't actually use glob() to filter names. It's just like calling os.listdir() but with more overhead.
    – BlackJack
    Commented Apr 7, 2018 at 13:21
  • @BlackJack You are completely right. Alas, I don't remember why I did this at the first place.
    – glglgl
    Commented Apr 9, 2018 at 11:46
0

Code to remove all png

args = ('rm', '-rf', '/path/to/files/temp/*.png')

subprocess.call('%s %s %s' % args, shell=True)

Not the answer you're looking for? Browse other questions tagged or ask your own question.