nushell / nushell/nushell

glob should not lstat with --no-dir

Open
#17,251 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

status:needs-triage
Dominant language
Rust
Stars
40.5k
Forks
2.3k
Avg merge
1d 14h
Merged PRs (30d)
79

Description

Bug report form
  • I have done a basic search of the issue tracker to find any existing issues that are similar.
  • I have checked that my version is at least the latest stable release available via my installation method.
Describe the bug

In the beginning, unix had stat() and no symlinks. Then symlinks were added, and lstat() for those rare rare situations that you actually care if something is a symlink.

Clearly glob is using lstat() and not stat() because if I do glob --no-dirs * it will return symlinks to dirs, totally contrary to the spirit of how unix is supposed to work, and contrary to the rational behavior of scripts.

Yes, I do note that there is a --no-symlink option, but we don't want that, we want symlinks, just not links to dirs.

And yes there is a --follow-symlinks option, but this is ass-backward. the UNIX philosophy is that no program should be aware of symlinks unless you take special action to tell it to be aware. The whole point of symlinks is completely defeated if the default situation is that programs will not follow them by default.

Now, I suppose you COULD make an argument that glob ** syntax that does a recursive search, you might not want that to follow links by default, as per the UNIX find command. But when it comes to files that you've ALREADY decided to consider in your traversal, aka for example, files in the current directory that you are examining ANYWAY, this case you MUST consider the link's target, not the fact it's a link. These are two very different situations, the decision whether to go globbing WITHIN a discovered symlink directory, and the decision to REPORT and RETURN a link that is in fact a directory, when you asked for --no-dirs. To confound those two ideas is to produce stupid results. I may well decide I don't actually want to go recursive globbing withing symlinked dirs, but that by no means indicates that I want to get back results that are symlink dirs when I asked for --no-dirs. And don't think about --no-symlink because I don't want to exclude files symlinked.

So in summary, returning a directory as a result with --no-dirs merely because it's a link = bad, against unix philosophy. But refusing to go recursive searching WITHIN symlink directories = possibly a good idea.

How to reproduce
  1. make a symlink to a directory in your cwd
  2. type glob --no-dirs * and see that the symlink to a directory is returned.
  3. Note that what should work fine: glob --no-dirs * | each { open $in } fails, when that should be a perfectly reasonable script.
Expected behavior

--no-dirs should never return dirs, even if they are symlinks to dirs.

Configuration
key value
version 0.109.1
major 0
minor 109
patch 1
branch makepkg
commit_hash cde5f7be8c813173e95ea65f96e79a133f587de7
build_os linux-x86_64
build_target x86_64-unknown-linux-gnu
rust_version rustc 1.91.1 (ed61e7d7e 2025-11-07) (Arch Linux rust 1:1.91.1-2)
cargo_version cargo 1.91.1 (ea2d97820 2025-10-10) (Arch Linux rust 1:1.91.1-2)
build_time 2025-12-03 07:57:38 +00:00
build_rust_channel release
allocator standard
features default, network, plugin, rustls-tls, sqlite, trash-support
installed_plugins
experimental_options example=false, reorder-cell-paths=true, pipefail=false, enforce-runtime-annotations=false

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing glob --no-dirs * with a symlink to a directory, then locate the glob implementation and its handling of --no-dirs and symlink targets. Done means the command excludes symlinks whose targets are directories while still returning symlinks to files, without changing recursive traversal behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust, shell
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.