Specific: effect of rm -r /./*

Solution 1:

The path you gave rm to delete was /./*. Let’s break this down:

  1. / The root mount point, such as Macintosh HD. This is the root of the disk, therefore an absolute path was given rather than a relative path operating on the current directory.
  2. ./ The current directory, which is now / by the path given so far. /. is equivalent to /, so // is the path so far, except duplicate directory delimiters are combined to a single delimiter, so / so far, the same as step 1.
  3. * Glob all files and folders at this level.

Therefore, the command given was to delete all files and folders starting at the root mount point, i.e. delete all files and folders on the entire volume.

macOS System Integrity Protection will prevent this mischief from causing much damage to the system’s core components, but your own files won’t be protected if you have given full disk access to the Terminal app. I hope you have a backup of the files you need, especially from the beginning of the disk depending when you stopped the command.

Solution 2:

A few recalls, of course everything is in man pages.

  • / is the "path separator", i.e. the character to separate folder (and optional terminal file) names.
  • paths can be either relative (to current working directory) or absolute (i.e. from the root folder) and a path beginning with / is absolute. Other are relative.
  • folders have "entries" which can be of various types, usually folders and files (but not only)
  • the rm command takes a list of files to delete, and has option "-r" which means : recursive, in that case, it can take a folder as argument.
    • folders always have special entries: "." and ".." which are special folder names corresponding to "current" and "parent" folders.
    • commands in terminal are executed by a shell, there are many shells, usually you can find your shell using "echo $SHELL", a popular one is "BASH". In most shells "*" is a "glob character", for instance, open bash manual (example: execute: "man bash" in a terminal) and then look for "Pathname Expansion", e.g. by typing "/Pathname Expansion", you can also look for "GLOBIGNORE". The behaviour of expansion can be controlled by some env vars and shell settings, but we can assume you use the default, which is "replace by all entries matching the glob, but not starting by '.' "

So, the shell will execute the command like this: rm -r /./*

  1. split command line in items, separated by "white spaces" : "rm" , "-r" and "/./*"
  2. apply a series or transformations, here only pathname expansion of the "" (example of other transformations: variable expansion) a. with "" it considers the item is a path b. The path is split into items separated by "/" : "" , "." and "" c. as the first element is empty, it is an absolute path starting at / (or you could consider that "/./" begins with "/" so it is absolute, and then remove from the list..) d. ok, in root folder look for entry "." : it is there, and in fact it reports back to the same folder it is in, i.e. "/" e. in this folder (/), look for all entries (folders and files) not string with "." f. replace the item that was globbed in step 1 with the list found, i.e. it will give something like: rm -r /./folder1 /./folder2 /./file1 ...
  3. execute the resulting command, by creating a new process whose executable is specified by the first item of list in 1. a. if the first argument starts with / it is an absolute path, else the executable is search in folders specified by variable PATH b. other items in list are provided as argument to the new process : "-r" , "/./folder1", "/./folder2", "/./file1" etc...
  4. the rm command will recursively delete folders and files as specified by the list of folders and files now expanded.

The real key here is that commands in terminal are executed by the shell, and a trick to know what is actually done is simply to add "echo" at the beginning of the command. In general it has no other effect than displaying the result of shell expansions. (unless you have backticks `` or $() command substitutions)

example here:

$ echo rm -r /./*
rm -r /./Applications /./Library /./Network /./System /./Users /./Volumes /./bin /./cores /./dev /./etc /./home /./installer.failurerequests /./net /./opt /./private /./sbin /./tmp /./usr /./var

My last advice: never do things like "rm -r *" or equivalent, for the following reasons: 1- usually it does not do what you want which is : delete everything in current folder. No, it deletes everything which do not start with "." (i.e. hidden files and folders) 2- it is dangerous !!! something the current working directory is not what you thing it is . 3- I find it much more efficient and safe to do the following, lets say you are in folder: /Users/laurent/folder_to_cleanup

$ cd ..
$ rm -fr folder_to_cleanup
$ mkdir folder_to_cleanup

This effectively safely deletes everything from the folder, including the folder, and then re-creates one if you need it.