nushell icon indicating copy to clipboard operation
nushell copied to clipboard

`rm -r link/` deletes symlink's target instead of symlink itself due to trailing slash

Open kik4444 opened this issue 1 year ago • 7 comments

Describe the bug

See title

How to reproduce

mkdir src
ln -s src/ link

ls -l . | select name type target
╭───┬──────┬─────────┬────────╮
│ # │ name │  type   │ target │
├───┼──────┼─────────┼────────┤
│ 0 │ link │ symlink │ src/   │
│ 1 │ src  │ dir     │        │
╰───┴──────┴─────────┴────────╯

rm -r link/

ls -l . | select name type target
╭───┬──────┬─────────┬────────╮
│ # │ name │  type   │ target │
├───┼──────┼─────────┼────────┤
│ 0 │ link │ symlink │ src/   │ # dangling symlink
╰───┴──────┴─────────┴────────╯

echo "Oh no I just deleted my real dir!"

Expected behavior

rm should return an error like the system rm:

^rm -r link/
rm: cannot remove 'link/': Not a directory

Screenshots

No response

Configuration

key value
version 0.92.1
branch
commit_hash
build_os linux-x86_64
build_target x86_64-unknown-linux-gnu
rust_version rustc 1.76.0 (07dca489a 2024-02-04) (built from a source tarball)
cargo_version cargo 1.76.0
build_time 1980-01-01 00:00:00 +00:00
build_rust_channel release
allocator mimalloc
features default, sqlite, trash, which
installed_plugins query

Additional context

rm -r link without a trailing slash works as expected.

kik4444 avatar Apr 08 '24 19:04 kik4444

(note: related to #2175, if not about the implementation, in how both are because nushell currently removes logical paths (symlinks) a bit too eagerly)

bew avatar Apr 09 '24 06:04 bew

I can't reproduce this. I'm deleting the symlink just fine.

yizhepku avatar Apr 14 '24 15:04 yizhepku

To reproduce the incorrect behavior, one has to write

rm -r link/

If one writes

rm -r link

it is indeed the link that gets deleted. Because tabcompletion adds the / at the end, it's easier to run into this bug in the shell itself. The original bug report doesn't include / at the end. It was probably missed while typing the report.

ahkrr avatar Apr 15 '24 14:04 ahkrr

You're right, I hadn't noticed that. I'll edit my post

kik4444 avatar Apr 15 '24 15:04 kik4444

I think this is expected behavior. POSIX says symlinks should be followed if there're trailing slashes. Also see this SE question.

yizhepku avatar May 03 '24 10:05 yizhepku

I think this is expected behavior. POSIX says symlinks should be followed if there're trailing slashes. Also see this SE question.

Wouldn't that mean that the system rm's behavior is non-posix compliant? Because the system rm refuses to delete a symlink with a trailing slash or its target dir.

And tbh, even if it's not posix compliant, I think so many people are used to this behavior by now that maybe it should be the default?

kik4444 avatar May 03 '24 14:05 kik4444

Wouldn't that mean that the system rm's behavior is non-posix compliant? Because the system rm refuses to delete a symlink with a trailing slash or its target dir.

If by "the system rm" you mean GNU coreutils, then yes, it behaves very strangely. Try this in Bash:

mkdir src
ln -s src link

rm -r link/         # rm: cannot remove 'link/': Not a directory
rm link/            # rm: cannot remove 'link/': Is a directory

Honestly, I'm not sure what to make of this. Seems like a bug of GNU coreutils to me.

yizhepku avatar May 03 '24 15:05 yizhepku