What is the difference between 'rm' and 'unlink'?
up vote
40
down vote
favorite
Assuming you know the target is a symbolic link and not a file, is there any difference between using rm and unlink to remove the link?
symlink rm
add a comment |
up vote
40
down vote
favorite
Assuming you know the target is a symbolic link and not a file, is there any difference between using rm and unlink to remove the link?
symlink rm
3
This is pretty well covered on ServerFault: serverfault.com/questions/38816/…
– slm♦
Aug 24 '14 at 19:21
@slm♦ The answers correspond to that question, but this question is different, it says: "Assuming you know the target is a symbolic link and not a file".
– Stéphane Gourichon
Mar 21 '15 at 20:02
add a comment |
up vote
40
down vote
favorite
up vote
40
down vote
favorite
Assuming you know the target is a symbolic link and not a file, is there any difference between using rm and unlink to remove the link?
symlink rm
Assuming you know the target is a symbolic link and not a file, is there any difference between using rm and unlink to remove the link?
symlink rm
symlink rm
asked Aug 24 '14 at 19:03
IQAndreas
3,992134163
3,992134163
3
This is pretty well covered on ServerFault: serverfault.com/questions/38816/…
– slm♦
Aug 24 '14 at 19:21
@slm♦ The answers correspond to that question, but this question is different, it says: "Assuming you know the target is a symbolic link and not a file".
– Stéphane Gourichon
Mar 21 '15 at 20:02
add a comment |
3
This is pretty well covered on ServerFault: serverfault.com/questions/38816/…
– slm♦
Aug 24 '14 at 19:21
@slm♦ The answers correspond to that question, but this question is different, it says: "Assuming you know the target is a symbolic link and not a file".
– Stéphane Gourichon
Mar 21 '15 at 20:02
3
3
This is pretty well covered on ServerFault: serverfault.com/questions/38816/…
– slm♦
Aug 24 '14 at 19:21
This is pretty well covered on ServerFault: serverfault.com/questions/38816/…
– slm♦
Aug 24 '14 at 19:21
@slm♦ The answers correspond to that question, but this question is different, it says: "Assuming you know the target is a symbolic link and not a file".
– Stéphane Gourichon
Mar 21 '15 at 20:02
@slm♦ The answers correspond to that question, but this question is different, it says: "Assuming you know the target is a symbolic link and not a file".
– Stéphane Gourichon
Mar 21 '15 at 20:02
add a comment |
3 Answers
3
active
oldest
votes
up vote
42
down vote
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 doing.
Breakdown
With unlink it's invoking the unlink() system call:
....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3) = 0
unlink("file1") = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
....
With rm it's a slightly different path:
....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK) = 0
unlinkat(AT_FDCWD, "file1", 0) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
...
The system calls unlink() and unlinkat() are essentially the same except for the differences described in this man page: http://linux.die.net/man/2/unlinkat.
excerpt
The unlinkat() system call operates in exactly the same way as either
unlink(2) or rmdir(2) (depending on whether or not flags includes the
AT_REMOVEDIR flag) except for the differences described in this manual
page.
If the pathname given in pathname is relative, then it is interpreted
relative to the directory referred to by the file descriptor dirfd
(rather than relative to the current working directory of the calling
process, as is done by unlink(2) and rmdir(2) for a relative
pathname).
If the pathname given in pathname is relative and dirfd is the special
value AT_FDCWD, then pathname is interpreted relative to the current
working directory of the calling process (like unlink(2) and
rmdir(2)).
If the pathname given in pathname is absolute, then dirfd is ignored.
1
Since it's givingAT_FDCWD, there's effectively no difference betweenunlinkandunlinkat.
– Barmar
Aug 27 '14 at 21:01
4
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
add a comment |
up vote
17
down vote
With a single file, rm and unlink do the same task, remove the file. As POSIX defined, rm and unlink both call to unlink() system call.
In GNU rm, it calls to unlinkat() system call, which is equivalent to the unlink() or rmdir() function except in the case where path specifies a relative path.
Note
On some systems, unlink can also remove directory. At least in GNU system, unlink can never delete the name of a directory.
add a comment |
up vote
9
down vote
POSIX specifies that the unlink utility calls the C library unlink function and nothing else. It takes no option. If you pass a valid path name to something which isn't a directory, and if you have write permissions to the directory where that object lives, then unlink will remove it.
rm is a traditional Unix command which has a bit of other functionality, and isn't quite a superset of unlink (see below).
Firstly, rm performs safety checks. If you try to rm an object to which you don't have write permissions (which are irrelevant to your ability to remove it: the directly permissions are!) rm nevertheless refuses unless -f is specified. rm normally complains if the file doesn't exist, as does unlink; however with -f, rm does not complain. This is often exploited in Makefiles (clean: @rm -f $(OBJS) ...) so make clean doesn't fail when there is nothing to remove.
Secondly, rm has the -i option for interactively confirming the delete.
Thirdly, rm has -r for recursively removing a directory, which is something that unlink isn't required to do, since the C library function doesn't do that.
The unlink utility isn't exactly a stripped-down rm. It performs a subset of what rm does, but it has semantics which is a combination of rm with -f and rm without -f.
Suppose you want to just remove a regular file regardless of what its own permissions are. Furthermore, suppose you want the command to fail if the file doesn't exist, or any other reason. Neither rm file nor rm -f file meets the requirements. rm file will refuse if the file isn't writable. But rm -f file will neglect to complain if the file is missing. unlink file does the job.
unlink was probably introduced because rm is too clever: sometimes you just want the pure Unix unlink semantics: "please make this directory entry go away if directory permissions allow".
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
42
down vote
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 doing.
Breakdown
With unlink it's invoking the unlink() system call:
....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3) = 0
unlink("file1") = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
....
With rm it's a slightly different path:
....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK) = 0
unlinkat(AT_FDCWD, "file1", 0) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
...
The system calls unlink() and unlinkat() are essentially the same except for the differences described in this man page: http://linux.die.net/man/2/unlinkat.
excerpt
The unlinkat() system call operates in exactly the same way as either
unlink(2) or rmdir(2) (depending on whether or not flags includes the
AT_REMOVEDIR flag) except for the differences described in this manual
page.
If the pathname given in pathname is relative, then it is interpreted
relative to the directory referred to by the file descriptor dirfd
(rather than relative to the current working directory of the calling
process, as is done by unlink(2) and rmdir(2) for a relative
pathname).
If the pathname given in pathname is relative and dirfd is the special
value AT_FDCWD, then pathname is interpreted relative to the current
working directory of the calling process (like unlink(2) and
rmdir(2)).
If the pathname given in pathname is absolute, then dirfd is ignored.
1
Since it's givingAT_FDCWD, there's effectively no difference betweenunlinkandunlinkat.
– Barmar
Aug 27 '14 at 21:01
4
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
add a comment |
up vote
42
down vote
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 doing.
Breakdown
With unlink it's invoking the unlink() system call:
....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3) = 0
unlink("file1") = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
....
With rm it's a slightly different path:
....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK) = 0
unlinkat(AT_FDCWD, "file1", 0) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
...
The system calls unlink() and unlinkat() are essentially the same except for the differences described in this man page: http://linux.die.net/man/2/unlinkat.
excerpt
The unlinkat() system call operates in exactly the same way as either
unlink(2) or rmdir(2) (depending on whether or not flags includes the
AT_REMOVEDIR flag) except for the differences described in this manual
page.
If the pathname given in pathname is relative, then it is interpreted
relative to the directory referred to by the file descriptor dirfd
(rather than relative to the current working directory of the calling
process, as is done by unlink(2) and rmdir(2) for a relative
pathname).
If the pathname given in pathname is relative and dirfd is the special
value AT_FDCWD, then pathname is interpreted relative to the current
working directory of the calling process (like unlink(2) and
rmdir(2)).
If the pathname given in pathname is absolute, then dirfd is ignored.
1
Since it's givingAT_FDCWD, there's effectively no difference betweenunlinkandunlinkat.
– Barmar
Aug 27 '14 at 21:01
4
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
add a comment |
up vote
42
down vote
up vote
42
down vote
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 doing.
Breakdown
With unlink it's invoking the unlink() system call:
....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3) = 0
unlink("file1") = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
....
With rm it's a slightly different path:
....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK) = 0
unlinkat(AT_FDCWD, "file1", 0) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
...
The system calls unlink() and unlinkat() are essentially the same except for the differences described in this man page: http://linux.die.net/man/2/unlinkat.
excerpt
The unlinkat() system call operates in exactly the same way as either
unlink(2) or rmdir(2) (depending on whether or not flags includes the
AT_REMOVEDIR flag) except for the differences described in this manual
page.
If the pathname given in pathname is relative, then it is interpreted
relative to the directory referred to by the file descriptor dirfd
(rather than relative to the current working directory of the calling
process, as is done by unlink(2) and rmdir(2) for a relative
pathname).
If the pathname given in pathname is relative and dirfd is the special
value AT_FDCWD, then pathname is interpreted relative to the current
working directory of the calling process (like unlink(2) and
rmdir(2)).
If the pathname given in pathname is absolute, then dirfd is ignored.
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 doing.
Breakdown
With unlink it's invoking the unlink() system call:
....
mmap(NULL, 106070960, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f6d025cc000
close(3) = 0
unlink("file1") = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
....
With rm it's a slightly different path:
....
ioctl(0, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid() = 1000
newfstatat(AT_FDCWD, "file1", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "file1", W_OK) = 0
unlinkat(AT_FDCWD, "file1", 0) = 0
lseek(0, 0, SEEK_CUR) = -1 ESPIPE (Illegal seek)
close(0) = 0
close(1) = 0
close(2) = 0
exit_group(0) = ?
+++ exited with 0 +++
...
The system calls unlink() and unlinkat() are essentially the same except for the differences described in this man page: http://linux.die.net/man/2/unlinkat.
excerpt
The unlinkat() system call operates in exactly the same way as either
unlink(2) or rmdir(2) (depending on whether or not flags includes the
AT_REMOVEDIR flag) except for the differences described in this manual
page.
If the pathname given in pathname is relative, then it is interpreted
relative to the directory referred to by the file descriptor dirfd
(rather than relative to the current working directory of the calling
process, as is done by unlink(2) and rmdir(2) for a relative
pathname).
If the pathname given in pathname is relative and dirfd is the special
value AT_FDCWD, then pathname is interpreted relative to the current
working directory of the calling process (like unlink(2) and
rmdir(2)).
If the pathname given in pathname is absolute, then dirfd is ignored.
edited Nov 29 '16 at 0:35
DepressedDaniel
3,375513
3,375513
answered Aug 24 '14 at 19:35
slm♦
244k66502669
244k66502669
1
Since it's givingAT_FDCWD, there's effectively no difference betweenunlinkandunlinkat.
– Barmar
Aug 27 '14 at 21:01
4
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
add a comment |
1
Since it's givingAT_FDCWD, there's effectively no difference betweenunlinkandunlinkat.
– Barmar
Aug 27 '14 at 21:01
4
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
1
1
Since it's giving
AT_FDCWD, there's effectively no difference between unlink and unlinkat.– Barmar
Aug 27 '14 at 21:01
Since it's giving
AT_FDCWD, there's effectively no difference between unlink and unlinkat.– Barmar
Aug 27 '14 at 21:01
4
4
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
It makes me happy to read this answer because I just "learned to fish" in a powerful, flexible way when often I get a fish or sometimes I "learn to fish" in a basic way on SO :-)
– sage
Jan 24 '17 at 19:21
add a comment |
up vote
17
down vote
With a single file, rm and unlink do the same task, remove the file. As POSIX defined, rm and unlink both call to unlink() system call.
In GNU rm, it calls to unlinkat() system call, which is equivalent to the unlink() or rmdir() function except in the case where path specifies a relative path.
Note
On some systems, unlink can also remove directory. At least in GNU system, unlink can never delete the name of a directory.
add a comment |
up vote
17
down vote
With a single file, rm and unlink do the same task, remove the file. As POSIX defined, rm and unlink both call to unlink() system call.
In GNU rm, it calls to unlinkat() system call, which is equivalent to the unlink() or rmdir() function except in the case where path specifies a relative path.
Note
On some systems, unlink can also remove directory. At least in GNU system, unlink can never delete the name of a directory.
add a comment |
up vote
17
down vote
up vote
17
down vote
With a single file, rm and unlink do the same task, remove the file. As POSIX defined, rm and unlink both call to unlink() system call.
In GNU rm, it calls to unlinkat() system call, which is equivalent to the unlink() or rmdir() function except in the case where path specifies a relative path.
Note
On some systems, unlink can also remove directory. At least in GNU system, unlink can never delete the name of a directory.
With a single file, rm and unlink do the same task, remove the file. As POSIX defined, rm and unlink both call to unlink() system call.
In GNU rm, it calls to unlinkat() system call, which is equivalent to the unlink() or rmdir() function except in the case where path specifies a relative path.
Note
On some systems, unlink can also remove directory. At least in GNU system, unlink can never delete the name of a directory.
edited Aug 25 '14 at 1:27
answered Aug 24 '14 at 19:26
cuonglm
101k23195296
101k23195296
add a comment |
add a comment |
up vote
9
down vote
POSIX specifies that the unlink utility calls the C library unlink function and nothing else. It takes no option. If you pass a valid path name to something which isn't a directory, and if you have write permissions to the directory where that object lives, then unlink will remove it.
rm is a traditional Unix command which has a bit of other functionality, and isn't quite a superset of unlink (see below).
Firstly, rm performs safety checks. If you try to rm an object to which you don't have write permissions (which are irrelevant to your ability to remove it: the directly permissions are!) rm nevertheless refuses unless -f is specified. rm normally complains if the file doesn't exist, as does unlink; however with -f, rm does not complain. This is often exploited in Makefiles (clean: @rm -f $(OBJS) ...) so make clean doesn't fail when there is nothing to remove.
Secondly, rm has the -i option for interactively confirming the delete.
Thirdly, rm has -r for recursively removing a directory, which is something that unlink isn't required to do, since the C library function doesn't do that.
The unlink utility isn't exactly a stripped-down rm. It performs a subset of what rm does, but it has semantics which is a combination of rm with -f and rm without -f.
Suppose you want to just remove a regular file regardless of what its own permissions are. Furthermore, suppose you want the command to fail if the file doesn't exist, or any other reason. Neither rm file nor rm -f file meets the requirements. rm file will refuse if the file isn't writable. But rm -f file will neglect to complain if the file is missing. unlink file does the job.
unlink was probably introduced because rm is too clever: sometimes you just want the pure Unix unlink semantics: "please make this directory entry go away if directory permissions allow".
add a comment |
up vote
9
down vote
POSIX specifies that the unlink utility calls the C library unlink function and nothing else. It takes no option. If you pass a valid path name to something which isn't a directory, and if you have write permissions to the directory where that object lives, then unlink will remove it.
rm is a traditional Unix command which has a bit of other functionality, and isn't quite a superset of unlink (see below).
Firstly, rm performs safety checks. If you try to rm an object to which you don't have write permissions (which are irrelevant to your ability to remove it: the directly permissions are!) rm nevertheless refuses unless -f is specified. rm normally complains if the file doesn't exist, as does unlink; however with -f, rm does not complain. This is often exploited in Makefiles (clean: @rm -f $(OBJS) ...) so make clean doesn't fail when there is nothing to remove.
Secondly, rm has the -i option for interactively confirming the delete.
Thirdly, rm has -r for recursively removing a directory, which is something that unlink isn't required to do, since the C library function doesn't do that.
The unlink utility isn't exactly a stripped-down rm. It performs a subset of what rm does, but it has semantics which is a combination of rm with -f and rm without -f.
Suppose you want to just remove a regular file regardless of what its own permissions are. Furthermore, suppose you want the command to fail if the file doesn't exist, or any other reason. Neither rm file nor rm -f file meets the requirements. rm file will refuse if the file isn't writable. But rm -f file will neglect to complain if the file is missing. unlink file does the job.
unlink was probably introduced because rm is too clever: sometimes you just want the pure Unix unlink semantics: "please make this directory entry go away if directory permissions allow".
add a comment |
up vote
9
down vote
up vote
9
down vote
POSIX specifies that the unlink utility calls the C library unlink function and nothing else. It takes no option. If you pass a valid path name to something which isn't a directory, and if you have write permissions to the directory where that object lives, then unlink will remove it.
rm is a traditional Unix command which has a bit of other functionality, and isn't quite a superset of unlink (see below).
Firstly, rm performs safety checks. If you try to rm an object to which you don't have write permissions (which are irrelevant to your ability to remove it: the directly permissions are!) rm nevertheless refuses unless -f is specified. rm normally complains if the file doesn't exist, as does unlink; however with -f, rm does not complain. This is often exploited in Makefiles (clean: @rm -f $(OBJS) ...) so make clean doesn't fail when there is nothing to remove.
Secondly, rm has the -i option for interactively confirming the delete.
Thirdly, rm has -r for recursively removing a directory, which is something that unlink isn't required to do, since the C library function doesn't do that.
The unlink utility isn't exactly a stripped-down rm. It performs a subset of what rm does, but it has semantics which is a combination of rm with -f and rm without -f.
Suppose you want to just remove a regular file regardless of what its own permissions are. Furthermore, suppose you want the command to fail if the file doesn't exist, or any other reason. Neither rm file nor rm -f file meets the requirements. rm file will refuse if the file isn't writable. But rm -f file will neglect to complain if the file is missing. unlink file does the job.
unlink was probably introduced because rm is too clever: sometimes you just want the pure Unix unlink semantics: "please make this directory entry go away if directory permissions allow".
POSIX specifies that the unlink utility calls the C library unlink function and nothing else. It takes no option. If you pass a valid path name to something which isn't a directory, and if you have write permissions to the directory where that object lives, then unlink will remove it.
rm is a traditional Unix command which has a bit of other functionality, and isn't quite a superset of unlink (see below).
Firstly, rm performs safety checks. If you try to rm an object to which you don't have write permissions (which are irrelevant to your ability to remove it: the directly permissions are!) rm nevertheless refuses unless -f is specified. rm normally complains if the file doesn't exist, as does unlink; however with -f, rm does not complain. This is often exploited in Makefiles (clean: @rm -f $(OBJS) ...) so make clean doesn't fail when there is nothing to remove.
Secondly, rm has the -i option for interactively confirming the delete.
Thirdly, rm has -r for recursively removing a directory, which is something that unlink isn't required to do, since the C library function doesn't do that.
The unlink utility isn't exactly a stripped-down rm. It performs a subset of what rm does, but it has semantics which is a combination of rm with -f and rm without -f.
Suppose you want to just remove a regular file regardless of what its own permissions are. Furthermore, suppose you want the command to fail if the file doesn't exist, or any other reason. Neither rm file nor rm -f file meets the requirements. rm file will refuse if the file isn't writable. But rm -f file will neglect to complain if the file is missing. unlink file does the job.
unlink was probably introduced because rm is too clever: sometimes you just want the pure Unix unlink semantics: "please make this directory entry go away if directory permissions allow".
answered Nov 29 '16 at 1:40
Kaz
4,46811431
4,46811431
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f151951%2fwhat-is-the-difference-between-rm-and-unlink%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
This is pretty well covered on ServerFault: serverfault.com/questions/38816/…
– slm♦
Aug 24 '14 at 19:21
@slm♦ The answers correspond to that question, but this question is different, it says: "Assuming you know the target is a symbolic link and not a file".
– Stéphane Gourichon
Mar 21 '15 at 20:02