Rm (Unix)

Shell command for deleting files

The `rm` command

Original author(s)| Ken Thompson, Dennis Ritchie
(AT&T Bell Laboratories)
Developer(s)| Various open-source and commercial developers
Initial release| November 3, 1971; 53 years ago (1971-11-03)
Written in| C
Operating system| Unix, Unix-like, V, Plan 9, Inferno, KolibriOS, IBM i
Platform| Cross-platform
Type| Command
License| coreutils: GPLv3+
Plan 9: MIT License

`rm`, short for remove, is a shell command for removing files (which includes special files such as directories) from the file system. The command may not actually delete a file (release its storage for reuse) since it only unlinks it – removes a hard link to a file via the `unlink()` system call. If a file has multiple links and less than all are removed, then the file remains in the file system; accessible via its other links. When a file's only link is removed, then the file is deleted – releasing its storage space for other use.

Generally, a deleted file's former storage space still contains the file's data until it is overwritten with another file's content. The data is not accessible via normal file operations but can be recovered via specialized tools. Since this is considered a security risk in some contexts, a hardened version of `cp` may wipe the file's storage area when the file is deleted. Commands such as shred and srm specifically provide data wiping.

Since `rm` does not provide a fallback to recover a file such as a recycle bin, its use involves the risk of accidentally losing information.[1] Users tend to wrap calls to `rm` in safety mechanisms to limit accidental deletion. There are undelete utilities that attempts to reconstruct the index and can bring the file back if its storage was not reused.

Originally, developed for Unix, today it is also available on Unix-like and non Unix-like systems, KolibriOS,[2] IBM i,[3] EFI shell.[4] and Windows (via UnxUtils).[5] The `del` command provides a similar capability in MS-DOS, OS/2, and Command Prompt.

Like `rm`, the `unlink` command also removes (unlinks) files, but only one file at a time.

## History

[edit]

On some old versions of Unix, the `rm` command would remove directories if they were empty.[6] This behaviour can still be obtained in some versions of `rm` with the `-d` flag, e.g., the BSDs (such as FreeBSD,[7] NetBSD,[8] OpenBSD[9] and macOS) derived from 4.4BSD-Lite2.

The version in GNU Core Utilities was written by Paul Rubin, David MacKenzie, Richard Stallman, and Jim Meyering.[10] This version provides a `-d` option to help with compatibility.[11] The same functionality is provided by the standard `rmdir` command.

## Options

[edit]

Options commonly provided by a command implementation:

* `-r`, recursive; remove directories and their content recursively
* `-i`, interactive; ask user to confirm deleting each file
* `-f`, force; ignore non-existent files and override any confirmation prompts (effectively canceling `-i`), does not allow removing files from a write-protected directory
* `-v`, verbose; log status
* `-d`, directory; remove any empty directories
* `--one-file-system`, only remove files on the same file system as the argument; ignore mounted file systems

## Use

[edit]

By default, `rm` removes specified files, but does not remove a directory.[12] For example, the following removes the file named foo

$ rm foo

But that command fails if foo is a directory. To delete directory foo:

$ rm -r foo

The command is often used with xargs to supply a list of files:

$ xargs rm < filelist

To remove all PNG images in all directories below the current one:

$ find . -name '*.png' -exec rm {} +

## Safety

[edit]

### Permissions

[edit]

On most file systems, removing a file requires write and execute permissions on the containing directory. Some may be confused that permissions on the file to be removed are irrelevant. However, the GNU implementation confirms removing a write-protected file unless the -f option is used.[13]

To remove a directory (using `-r`), its contents must be removed, recursively. This requires the user to have read, write and execute permissions to the directory (if it's not empty) and any non-empty subdirectories recursively. Read permission is needed to list the contents of the directory. This sometimes leads to an odd situation where a non-empty directory cannot be removed because the user doesn't have write permission to it and so cannot remove its contents, but if the same directory were empty, the user would be able to remove it.[14]

If a file resides in a directory with the sticky bit set, then removing the file requires the user to own the file.

### Preventing accidental deletion

[edit]

Commands like `rm -rf *` are relatively risky since they can delete many files in an unrecoverable way. Such commands are sometimes referenced in anecdotes about disastrous mistakes,[15] such as during the production of the film Toy Story 2.[16]

To minimize the risk of accidental file deletions, a common technique is to hide the default `rm` command behind an alias or a function that includes the interactive option. For example:

alias rm="rm -i"

rm () { /bin/rm -i "$@" ; }

Then, by default, `rm` requires the user to confirm removing each file by pressing `Y` or `N` plus `Return`. To bypass confirmation, a user can include the `-f` option (as the option specified later on the expanded command line "`rm -i -f`" takes precedence).

Unfortunately this can lead to other accidental removals since it trains users to be careless about the wildcards they hand to `rm`, as well as encouraging a tendency to mindlessly press `Y` and `Return` to confirm.[citation needed] Users have even been seen going as far as using `yes | rm files`, which automatically confirms the deletion of each file. [citation needed]

A compromise that allows users to confirm just once, encourages proper wildcarding, and makes verification of the list easier can be achieved with something like:

if [ -n "$PS1" ] ; then
rm ()

ls -FCsd "$@"
echo 'remove[ny]? ' | tr -d '\012' ; read
if [ "_$REPLY" = "_y" ]; then
/bin/rm -rf "$@"
else
echo '(cancelled)'

Arguably, this function should not be made into a shell script, which would run a risk of it being found ahead of the system `rm` in the search path, nor should it be allowed in non-interactive shells where it could break batch jobs. Enclosing the definition in the `if [ -n "$PS1" ] ; then ....  ; fi` construct protects against the latter.

Other commands are designed to prevent accidental deletion; including `safe-rm`[17] and `trash`.[18]

### Protection of the filesystem root

[edit]

The `rm -rf /` command, if run by a superuser, causes every file of the file system to be deleted. For safety, Sun Microsystems introduced special protection for this command in Solaris 10 (first released in 2005). The implementation reports that removing `/` is not allowed.[19] Shortly thereafter, the same functionality was introduced into the FreeBSD implementation.[20] The GNU version refuses to execute `rm -rf /` unless the `--preserve-root` option is included,[21] which has been the default since version 6.4 of GNU Core Utilities. In newer systems, this failsafe is always active, even without the option. To run the command, user must bypass the failsafe by adding the option `--no-preserve-root`, even if they are the superuser.

## Limitations

[edit]

This section may contain material unrelated to the topic of the article. Please help improve this section or discuss this issue on the talk page. (January 2025) (Learn how and when to remove this message)

|

The GNU Core Utilities implementation has limits on command line arguments. Arguments are nominally limited to 32 times the kernel's allocated page size. Systems with 4KB page size would thus have a argument size limit of 128KB.[22] For command-line arguments before kernel 2.6.23, the limits were defined at kernel compile time and can be modified by changing the variable `MAX_ARG_PAGES` in `include/linux/binfmts.h` file.[23][24] Newer kernels[which?] limit the maximum argument length to 25% of the maximum stack limit (ulimit -s). Exceeding the limit results in an error.[25][clarification needed]

## See also

[edit]

* deltree – Command in DOS and Windows 9xPages displaying short descriptions of redirect targets
* dsw (command) – Obsolete shell command for deleting files with unutterable names

## References

[edit]

1. ^ "Unix - Frequently Asked Questions (3/7) [Frequent posting]Section - How do I "undelete" a file?". www.faqs.org.
2. ^ "Shell - KolibriOS wiki". wiki.kolibrios.org.
3. ^ IBM. "IBM System i Version 7.2 Programming Qshell" (PDF). IBM. Retrieved 2020-09-05.
4. ^ "EFI Shells and Scripting". Intel. Retrieved 2013-09-25.
5. ^ "Native Win32 ports of some GNU utilities". unxutils.sourceforge.net.
6. ^ "rm page from Section 1 of the unix 8th manual". man.cat-v.org.
7. ^ "RM(1)", FreeBSD-5.4-RELEASE, retrieved February 5, 2015
8. ^ "RM(1)", NetBSD-2.0, retrieved February 5, 2015
9. ^ "RM(1)", OpenBSD-3.6, retrieved February 5, 2015
10. ^ "rm(1): remove files/directories - Linux man page". linux.die.net.
11. ^ Krzysztof Goj (January 22, 2012). "rm: new option --dir (-d) to remove empty directories". coreutils.git.
12. ^ "rm(1) - Linux manual page". man7.org.
13. ^ "Linux rm command help and examples". ComputerHope. 24 January 2018. Archived from the original on April 16, 2016. Retrieved 24 January 2019.
14. ^ McElhearn, Kirk (2 January 2014). "Master the command line: Deleting files and folders". Macworld. Retrieved 24 January 2019.
15. ^ Gite, Vivek. "Linux/UNIX: Delete a file". Nixcraft. Retrieved 24 November 2011.
16. ^ Panzarino, Matthew (21 May 2012). "How Toy Story 2 Got Deleted Twice, Once on Accident, Again on purpose". TNW | Media. Retrieved 27 September 2022.
17. ^ "Safe-rm in Launchpad". Launchpad.
18. ^ "andreafrancia/trash-cli". September 12, 2020 - via GitHub.
19. ^ "Meddling in the Affairs of Wizards". Archived from the original on 2016-11-03.
20. ^ "The previous commit added code to rm(1) to warn about and remove any · freebsd/freebsd@d6b7bd9". GitHub.
21. ^ "rm invocation (GNU Coreutils)". www.gnu.org.
22. ^ "How to get around the Linux "Too Many Arguments" limit". Stackoverflow. "With the coupling of ARG_MAX to ulim -s / 4 came the introduction of MAX_ARG_STRLEN as max. length of an argument [...] MAX_ARG_STRLEN is defined as 32 times the page size in linux/include/uapi/linux/binfmts.h [...] The default page size is 4 KB so you cannot pass arguments longer than 128 KB [...]"
23. ^ "Linux_2_6_23 - Linux Kernel Newbies". kernelnewbies.org.
24. ^ "kernel/git/torvalds/linux.git - Linux kernel source tree". git.kernel.org.
25. ^ ""Argument list too long": Beyond Arguments and Limitations | Linux Journal". www.linuxjournal.com.

## Further reading

[edit]

* McElhearn, Kirk (2006). The Mac OS X Command Line: Unix Under the Hood. John Wiley & Sons. ISBN 978-0470113851.

## External links

[edit]

The Wikibook Guide to Unix has a page on the topic of: rm

* `rm`: remove directory entries – Shell and Utilities Reference, The Single UNIX Specification, Version 5 from The Open Group
* `rm(1)` – Plan 9 Programmer's Manual, Volume 1
* `rm(1)` – Inferno General commands Manual

* v
* t
* e

Unix command-line interface programs and shell builtins

File system|

* cat
* chattr
* chmod
* chown
* chgrp
* cksum
* cmp
* cp
* dd
* du
* df
* file
* fuser
* ln
* ls
* mkdir
* mv
* pax
* pwd
* rm
* rmdir
* split
* tee
* touch
* type
* umask

Processes|

* at
* bg
* crontab
* fg
* kill
* nice
* ps
* time

User environment|

* env
* exit
* logname
* mesg
* talk
* tput
* uname
* who
* write

Text processing|

* awk
* basename
* comm
* csplit
* cut
* diff
* dirname
* ed
* ex
* fold
* head
* iconv
* join
* m4
* more
* nl
* paste
* patch
* printf
* read
* sed
* sort
* strings
* tail
* tr
* troff
* uniq
* vi
* wc
* xargs

Shell builtins|

* alias
* cd
* echo
* test
* unset
* wait

Searching|

* find
* grep

Documentation|

* man

Software development|

* ar
* ctags
* lex
* make
* nm
* strip
* yacc

Miscellaneous|

* bc
* cal
* expr
* lp
* od
* sleep
* true and false

* Categories
* Standard Unix programs
* Unix SUS2008 utilities
* List

* v
* t
* e

Plan 9 command-line interface programs and shell builtins

File system|

* chmod
* chgrp
* cmp
* cp
* dd
* du
* file
* gzip
* ls
* mkdir
* pwd
* rm
* split
* tee
* touch

Processes|

* kill
* ps

User environment|

* passwd
* who

Text processing|

* awk
* basename
* comm
* diff
* ed
* eqn
* join
* sed
* sort
* spell
* strings
* tail
* tr
* troff
* uniq
* wc

Shell builtins|

* echo
* test

Networking|

* ip/ipconfig
* ip/ping
* netstat

Searching|

* grep

Software development|

* ar
* hoc
* lex
* nm
* strip
* yacc

Miscellaneous|

* bc
* cal
* fortune
* sleep

* Category

* v
* t
* e

GNU Core Utilities command-line interface programs

File system|

* chcon
* chmod
* chown
* chgrp
* cksum
* cp
* dd
* df
* dir
* dircolors
* install
* ln
* ls
* mkdir
* mkfifo
* mknod
* mktemp
* mv
* realpath
* rm
* rmdir
* shred
* sync
* touch
* truncate
* vdir

Text utilities|

* b2sum
* base32
* base64
* cat
* cksum
* comm
* csplit
* cut
* expand
* fmt
* fold
* head
* join
* md5sum
* nl
* numfmt
* od
* paste
* ptx
* pr
* sha1sum
* shuf
* sort
* split
* sum
* tac
* tail
* tr
* tsort
* unexpand
* uniq
* wc

Shell utilities|

* arch
* basename
* chroot
* date
* dirname
* du
* echo
* env
* expr
* factor
* false
* groups
* hostid
* id
* link
* logname
* nice
* nohup
* nproc
* pathchk
* pinky
* printenv
* printf
* pwd
* readlink
* runcon
* seq
* sleep
* stat
* stdbuf
* stty
* tee
* test
* timeout
* true
* tty
* uname
* unlink
* uptime
* users
* who
* whoami
* yes

*[v]: View this template
*[t]: Discuss this template
*[e]: Edit this template