Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow "-t c" and "-t b" for block and character files on linux. #1213

Closed
alanxoc3 opened this issue Dec 19, 2022 · 8 comments
Closed

Allow "-t c" and "-t b" for block and character files on linux. #1213

alanxoc3 opened this issue Dec 19, 2022 · 8 comments

Comments

@alanxoc3
Copy link

See title. Find supports both those options, but fd doesn't. Excerpt from the find man page:

-type c
    File is of type c:
    b      block (buffered) special
    c      character (unbuffered) special

Seems like fd should support these for linux systems too...

@tmccombs
Copy link
Collaborator

What is your use case for needing those flags?

@alanxoc3
Copy link
Author

Just scripting with the /dev directory. I'm using find though, so I don't need this feature. Mainly suggested because find supports it and this is a "find replacement". It's also a bit confusing when you can see all the device files by default:

> fd '' /dev
/dev/cpu/
/dev/cpu/0/
/dev/cpu/0/cpuid
/dev/cpu/0/msr
....

But there is no way to filter out the directories with just fd (because cpuid and msr are character special files).

@tmccombs
Copy link
Collaborator

Mainly suggested because find supports it and this is a "find replacement"

fd is not intended to have every feature that find has. From the README:

While it does not aim to support all of find's powerful functionality, it provides sensible (opinionated) defaults for a majority of use cases

(emphasis added)

there is no way to filter out the directories with just fd (because cpuid and msr are character special files)

hmm, it's actually a little surprising to me that character and block special files are excluded when you use -t f. although in a sense that makes sense.

There is some discussion of this issue in #511.

I wonder if maybe it does make sense to add a new "file type" for "anything that isn't a directory". Even if you don't care about character or block devices, that could be more convenient that needing to use -t f -t l -t s -t p in order to get all non-directory files. Perhaps "D" and "non-directory" could be used as the keys?

@alanxoc3
Copy link
Author

alanxoc3 commented Dec 20, 2022

In my opinion, adding a "-t D" option will just make the "-t" option even more confusing than it currently is.

My current problem with the "-t" option in general is that it is mixing filetypes with special things:

These are file types. Any "file" on a system can only match one of these:
    f, file
    d, directory
    l, symlink
    s, socket
    p, pipe

These are not file types. They are file properties, making the "-t" command a bit awkward to use:
    x, executable
    e, empty

If it's okay to slightly change the commandline API, here is an alternative proposal...

The existing "-S, size" option could replace "-t e" if you allow any file type to be used with "-S" (currently it looks like "-S" implies a "-t f"). Here's a tiny test to show that would work:

> mkdir what
> stat what | rg Size
  Size: 0               Blocks: 0          IO Block: 4096   directory
> touch what/file
> stat what | rg Size
  Size: 8               Blocks: 0          IO Block: 4096   directory
> rm what/file
> stat what | rg Size
  Size: 0               Blocks: 0          IO Block: 4096   directory

So, if "-S" does allow any file type, then "-t e" could just be rewritten as "-S 0b". You could go further by implying a "b" if there is no letter after the number, so "-S 0" would work too.

A better way to represent "-x" would be an extra "mode" option:

-m, --mode
    Like chmod maybe. A few possible examples:

    -m +111 # file must have have 111 permissions, but doesn't need to match exactly (555 or 777 would work too)
    -m  111 # file must have exactly permissions 111
    -m -111 # file can't have any execute permissions (444, 400, 222 would all work. 544 would not work)

So instead of "-t x", you could be more specific: "-m +100", only executable for the user.

And finally, instead of "-D", maybe you could add the "!" operator to "-t" (similar to how it's already on "-o"). This assumes the "-t x" and "-t e" options no longer exist:

fd -t !f # include everything except files
fd -t !d # include everything except dirs
fd -t !d -t !f # include everything except files and directories

# weirder cases (order technically matters in some):
fd -t !f -t f # include everything
fd -t f -t !f # include everything
fd -t !f -t d # include everything except files
fd -t d -t !f # include only directories

(Disclaimer, I haven't used windows in a decade so I don't know how this behaves on windows.)

What are your thoughts?

@tavianator
Copy link
Collaborator

I personally think --empty as an alias for --size=0 makes more sense than -t e.

-t x is not equivalent to any --mode-style option because it means executable for the current user. I do agree that "executable" is not really a file type either, so maybe --executable would be better.

I think for non-directories etc., -t '!d' would be nice syntax. Technically -type D already means something to GNU find (it matches Solaris doors).

As far as the original feature request, -t b and -t c would be easy enough to implement. Considering how often I run lsblk, I at least see why someone would want fd . /dev -t b. It does have the disadvantage of being hard to test (e.g. bfs has no test coverage for block devices).

@alanxoc3
Copy link
Author

One more comment on the original request for -t b and -t c. Those are also the only other file types on a linux system that fd doesn't support. There aren't anymore than that as far as I'm aware, so it's unlikely anyone will be requesting new file types to be added after this.

And I now see the issue with -t x not correctly porting to --mode +100 now. You could technically replace -t x with something like:

fd -o $(whoami) --mode +100

But that is slightly more work for the user. I'd be happy either way, as long as -t x could be moved out of the -t option.

@tmccombs
Copy link
Collaborator

There was discussion about splitting out the empty and executable "file types" before in #823.

Personally, I tend to agree that it would make more sense to have separate --empty and --executable options, or similar.

@sharkdp
Copy link
Owner

sharkdp commented Jan 13, 2023

It looks like I'm pretty much alone with my opinion expressed in #823 (comment). I am inclined to agree with the opinions expressed here (#1213 (comment)). However, I would first like to see a more detailed proposal on the required (breaking) changes. And some more thought on the CLI (for example: if we want a negate-option for --type, do we really want the new options to be --empty and --executable... because those would not allow for similar negation). For example, there is an older proposal by @tmccombs here #847 with a different interface.

It will only be a few more years until we've finally come full circle and fds interface looks exactly like find, except for the extra dash in long options 🙃

As far as the original feature request, -t b and -t c would be easy enough to implement.

Okay, let's do that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants