0

Suppose, we have the following files in a directory:

test.txt
test.txt~
/subdir
  test1.txt
  test1.txt~

When I run rm -r ./*.*~ inside top dir only test.txt~ is removed.

Why doesn't it perform the recursive removal despite the fact that I used recursive flag?

You can reproduce my case with the following script:

#create dir and 1-st level test files
mkdir dir
cd dir
touch test.txt
touch test.txt~

#create subdir and 2-nd level test files
mkdir subdir
cd subdir/
touch test1.txt~
touch test1.txt

cd ..
rm -r ./*.*~
user4035
  • 1,115

2 Answers2

6

Your rm -r *.*~ (same as rm -r ./*.*~) would remove files and directories matching *.*~ that is files and directories whose name contain a dot and ends with a ~

But subdir doe not contain any dot, so does not fit.

Read glob(7) and remember that it is your shell (not the /bin/rm program!) which does the globbing.

So what is happening is that you type rm -r ./*.*~ to your shell. Your shell is expanding that to rm -r ./test.txt~; then it finds the /bin/rm program in your $PATH, calls fork(2) to create a child process, and then execve(2) on /bin/rm program, with an argument array of rm -rf ./test.txt~ so rm does not even see ./subdir

To have every backup file removed in any direct subdirectory, type rm */*.*~; with recent bash (version 4 or later) and zsh you could remove any backup file even deep in the file tree with rm **/*.*

A possible way to understand what the shell is doing is to replace your command (e.g. rm) with echo. That should give you the expansion (but read echo(1), since echo is understanding some options like -n). On some good shells, you could even use the tab key for autocompletion. I'm using zsh as my interactive shell because I like its autocompletion features.

At last, rm(1) knows about -i (asking you interactively before removal). So I'll suggest rm -i **/*~

BTW, if you don't know about version control systems, it is time to learn them (I strongly recommend using git....), especially for "source" code like files (C or Python programs, shell scripts, etc etc etc ...) and you won't need backup files.

5

*.*~ does not expand to any directories, it will just match any file or directory in the current directory that has a . in it somewhere and ends in ~

If you would like to find all the files that end in ~ from the directory you're in I would use find like

find -type f -name '*~' -delete
DopeGhoti
  • 76,081
Eric Renouf
  • 18,431