The Stack Overflow podcast is back! Listen to an interview with our new CEO.

Hot answers tagged

280

The find command is the primary tool for recursive file system operations. Use the -type d expression to tell find you're interested in finding directories only (and not plain files). The GNU version of find supports the -empty test, so $ find . -type d -empty -print will print all empty directories below your current directory. Use find ~ -… or find "$...


265

That is evil: rm -r is not for deleting files but for deleting directories. Luckily there are probably no directories matching *.o. What you want is possible with zsh but not with sh or bash (new versions of bash can do this, but only if you enable the shell option globstar with shopt -s globstar). The globbing pattern is **/*.o but that would not be ...


246

-delete will perform better because it doesn't have to spawn an external process for each and every matched file. It is possible that you may see -exec rm {} \; often recommended because -delete does not exist in all versions of find. I can't check right now but I'm pretty sure I've used a find without it. Both methods should be "safe". EDIT per comment ...


240

Be careful with special file names (spaces, quotes) when piping to rm. There is a safe alternative - the -delete option: find /path/to/directory/ -mindepth 1 -mtime +5 -delete That's it, no separate rm call and you don't need to worry about file names. Replace -delete with -depth -print to test this command before you run it (-delete implies -depth).


222

Combining GNU find options and predicates, this command should do the job: find . -type d -empty -delete -type d restricts to directories -empty restricts to empty ones -delete removes each directory The tree is walked from the leaves without the need to specify -depth as it is implied by -delete.


217

The following command will do it for you. Use caution though. rm -rf directoryname


213

Using rsync is surprising fast and simple. mkdir empty_dir rsync -a --delete empty_dir/ yourdirectory/ @sarath's answer mentioned another fast choice: Perl! Its benchmarks are faster than rsync -a --delete. cd yourdirectory perl -e 'for(<*>){((stat)[9]<(unlink))}' Sources: https://stackoverflow.com/questions/1795370/unix-fast-remove-...


195

Find can execute arguments with the -exec option for each match it finds. It is a recommended mechanism because you can handle paths with spaces/newlines and other characters in them correctly. You will have to delete the contents of the directory before you can remove the directory itself, so use -r with the rm command to achieve this. For your example you ...


194

sudo touch /bin/rm && sudo chmod +x /bin/rm apt-get download coreutils sudo dpkg --unpack coreutils* And never again. Why didn't you use sudo with apt-get? Because the download command doesn't require it: download download will download the given binary package into the current directory. So, unless you are in some ...


112

The kernel interprets the line starting with #! and uses it to run the script, passing in the script's name; so this ends up running /bin/rm scriptname which deletes the script. (As Stéphane Chazelas points out, scriptname here is sufficient to find the script — if you specified a relative or absolute path, that's passed in as-is, otherwise whatever path ...


106

debian and its derivatives (and probably most other distributions) come with busybox which is used in the initramfs. busybox bundles most core command line utilities in a single executable. You can temporarily symlink /bin/rm to /bin/busybox: ln -s busybox /bin/rm To get a working rm (after which you can do your apt-get install --reinstall coreutils). ...


104

All rm needs is write+execute permission on the parent directory. The permissions of the file itself are irrelevant. Here's a reference which explains the permissions model more clearly than I ever could: Any attempt to access a file's data requires read permission. Any attempt to modify a file's data requires write permission. Any attempt to ...


100

The reason why this is permitted is related to what removing a file actually does. Conceptually, rm's job is to remove a name entry from a directory. The fact that the file may then become unreachable if that was the file's only name and that the inode and space occupied by the file can therefore be recovered at that point is almost incidental. The name of ...


97

You can use rm -v to have rm print one line per file deleted. This way you can see that rm is indeed working to delete files. But if you have billions of files then all you will see is that rm is still working. You will have no idea how many files are already deleted and how many are left. The tool pv can help you with a progress estimation. http://www....


89

Removing the current directory does not affect the file system integrity or its logical organization. Preventing . removal is done to follow the POSIX standard which states in the rmdir(2) manual page: If the path argument refers to a path whose final component is either dot or dot-dot, rmdir() shall fail. One rationale can be found in the rm manual ...


85

* matches all non-dot-files, .[!.]* matches all dot files except . and files whose name begins with .., and ..?* matches all dot-dot files except ... Together they match all files other than . and ... If any of these three patterns matches nothing, it expands to itself; rm -f doesn't care about non-existent arguments, so this doesn't matter. rm -rf ..?* .[!....


75

Edit based on updated question: To avoid being asked about removing files, add the -f ("force") option: rm -f /path/to/file This has one side effect you should be aware of: If any of the given paths do not exist, it will not report this, and it will return successfully: $ rm -f /nonexistent/path $ echo $? 0 Original answer: Here's one simple solution: ...


75

set -u or set -o nounset This would make the current shell treat expansions of unset variables as an error: $ unset build $ set -u $ rm -rf "$build"/* bash: build: unbound variable set -u and set -o nounset are POSIX shell options. An empty value would not trigger an error though. For that, use $ rm -rf "${build:?Error, variable is empty or unset}"/* ...


73

find is very useful for selectively performing actions on a whole tree. find . -type f -name ".Apple*" -delete Here, the -type f makes sure it's a file, not a directory, and may not be exactly what you want since it will also skip symlinks, sockets and other things. You can use ! -type d, which literally means not directories, but then you might also ...


69

You've explained the situation very well. The final piece to the puzzle is that unzip can handle wildcards itself: http://www.info-zip.org/mans/unzip.html ARGUMENTS file[.zip] ... Wildcard expressions are similar to those supported in commonly used Unix shells (sh, ksh, csh) and may contain: * matches a sequence of 0 or more ...


67

Here is a portable still faster than the accepted answer way. Using a + instead of a semicolon as find command terminator is optimizing the CPU usage. That can be significant if you have a lot of .svn sub-directories: find . -name .svn -type d -exec rm -rf {} + Note also that you never1 need to quote the curly braces here. 1 Unless you use the fish shell....


63

Make the file immutable with the i attribute. chattr +i file.desktop see man chattr for more information.


63

Please make sure to read the alternative answer. It's even more to the point although not voted as high at this point. You can use this to delete all symbolic links: find -type l -delete with modern find versions. On older find versions it may have to be: find -type l -exec rm {} \; # or find -type l -exec unlink {} \; To limit to a certain link target,...


61

In BASH you can use the trailing slash (I think it should work in any POSIX shell): rm -R -- */ Note the -- which separates options from arguments and allows one to remove entries starting with a hyphen - otherwise after expansion by the shell the entry name would be interpreted as an option by rm (the same holds for many other command line utilities). ...


59

The latest (as of 2017) version of the POSIX spec for the rm utility is here (and the previous one there) and forbids the deletion of . and ... If either of the files dot or dot-dot are specified as the basename portion of an operand (that is, the final pathname component) or if an operand resolves to the root directory, rm shall write a diagnostic ...


58

Use the -f option. It will silently ignore nonexistent files. From man rm: -f, --force ignore nonexistent files and arguments, never prompt [The "never prompt" part means that (a) -f overrides any previously specified -i or -I option, and (b) write-protected files will be deleted without asking.] Example Without -f, rm will complain about ...


57

That's not quite how the -r switch of rm works: -r, -R, --recursive remove directories and their contents recursively rm has no file searching functionality, its -r switch does not make it descend into local directories and identify files matching the pattern you give it. Instead, the pattern (*.o) is expanded by the shell and rm will descend ...


56

If a running program still has the deleted file open, you can recover the file through the open file descriptor in /proc/[pid]/fd/[num]. To determine if this is the case, you can attempt the following: $ lsof | grep "/path/to/file" If the above gives output of the form: progname 5383 user 22r REG 8,1 16791251 265368 /path/to/file take note ...


56

Anytime you have these types of questions it's best to conceive of a little test to see what's actually happening. For this you can use strace. unlink $ touch file1 $ strace -s 2000 -o unlink.log unlink file1 rm $ touch file1 $ strace -s 2000 -o rm.log rm file1 When you take a look at the 2 resulting log files you can "see" what each call is actually ...


56

This almost made me wince. You might want to stop pointing that shotgun at your foot. Basically any kind of parsing of ls is going to be more complicated and error-prone than established methods like find [...] -exec or globs. Unless someone installed a troll distro for you, your shell has Tab completion. Just type rm google and press Tab. If it doesn't ...


Only top voted, non community-wiki answers of a minimum length are eligible