Add new --type socket and --type pipe filters

closes #511
This commit is contained in:
sharkdp 2020-04-16 09:41:24 +02:00 committed by David Peter
parent 4287cddc00
commit cb56add1d8
7 changed files with 49 additions and 8 deletions

View file

@ -12,9 +12,10 @@
This can be useful to speed up searches in cases where you know that there are only N results. This can be useful to speed up searches in cases where you know that there are only N results.
Using this option is also (slightly) faster than piping to `head -n <count>` where `fd` can only Using this option is also (slightly) faster than piping to `head -n <count>` where `fd` can only
exit when it finds the search results `<count> + 1`. exit when it finds the search results `<count> + 1`.
- Add the alias `-1` for `--max-results=1`, see #561. (@SimplyDanny).
- Add new `--type socket` and `--type pipe` filters, see #511.
- Add new `--min-depth <depth>` and `--exact-depth <depth>` options in addition to the existing option - Add new `--min-depth <depth>` and `--exact-depth <depth>` options in addition to the existing option
to limit the maximum depth. See #404. to limit the maximum depth. See #404.
- Add the alias `-1` for `--max-results=1`, see #561. (@SimplyDanny).
- Support additional ANSI font styles in `LS_COLORS`: faint, slow blink, rapid blink, dimmed, hidden and strikethrough. - Support additional ANSI font styles in `LS_COLORS`: faint, slow blink, rapid blink, dimmed, hidden and strikethrough.
## Bugfixes ## Bugfixes

4
doc/fd.1 vendored
View file

@ -129,6 +129,10 @@ symbolic links
executable (files) executable (files)
.IP "e, empty" .IP "e, empty"
empty files or directories empty files or directories
.IP "s, socket"
sockets
.IP "p, pipe"
named pipes (FIFOs)
.RE .RE
.RS .RS

View file

@ -228,11 +228,15 @@ pub fn build_app() -> App<'static, 'static> {
"executable", "executable",
"e", "e",
"empty", "empty",
"s",
"socket",
"p",
"pipe",
]) ])
.hide_possible_values(true) .hide_possible_values(true)
.help( .help(
"Filter by type: file (f), directory (d), symlink (l),\nexecutable (x), \ "Filter by type: file (f), directory (d), symlink (l),\nexecutable (x), \
empty (e)", empty (e), socket (s), pipe (p)",
) )
.long_help( .long_help(
"Filter the search by type (multiple allowable filetypes can be specified):\n \ "Filter the search by type (multiple allowable filetypes can be specified):\n \
@ -240,7 +244,9 @@ pub fn build_app() -> App<'static, 'static> {
'd' or 'directory': directories\n \ 'd' or 'directory': directories\n \
'l' or 'symlink': symbolic links\n \ 'l' or 'symlink': symbolic links\n \
'x' or 'executable': executables\n \ 'x' or 'executable': executables\n \
'e' or 'empty': empty files or directories", 'e' or 'empty': empty files or directories\n \
's' or 'socket': socket\n \
'p' or 'pipe': named pipe (FIFO)",
), ),
) )
.arg( .arg(

View file

@ -4,7 +4,7 @@ use std::ffi::OsStr;
use std::fs; use std::fs;
use std::io; use std::io;
#[cfg(any(unix, target_os = "redox"))] #[cfg(any(unix, target_os = "redox"))]
use std::os::unix::fs::PermissionsExt; use std::os::unix::fs::{PermissionsExt, FileTypeExt};
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use crate::walk; use crate::walk;
@ -67,6 +67,26 @@ pub fn is_empty(entry: &walk::DirEntry) -> bool {
} }
} }
#[cfg(any(unix, target_os = "redox"))]
pub fn is_socket(ft: &fs::FileType) -> bool {
ft.is_socket()
}
#[cfg(windows)]
pub fn is_socket(_: &fs::FileType) -> bool {
false
}
#[cfg(any(unix, target_os = "redox"))]
pub fn is_pipe(ft: &fs::FileType) -> bool {
ft.is_fifo()
}
#[cfg(windows)]
pub fn is_pipe(_: &fs::FileType) -> bool {
false
}
#[cfg(any(unix, target_os = "redox"))] #[cfg(any(unix, target_os = "redox"))]
pub fn osstr_to_bytes(input: &OsStr) -> Cow<[u8]> { pub fn osstr_to_bytes(input: &OsStr) -> Cow<[u8]> {
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;

View file

@ -3,6 +3,8 @@ pub struct FileTypes {
pub files: bool, pub files: bool,
pub directories: bool, pub directories: bool,
pub symlinks: bool, pub symlinks: bool,
pub sockets: bool,
pub pipes: bool,
pub executables_only: bool, pub executables_only: bool,
pub empty_only: bool, pub empty_only: bool,
} }
@ -13,6 +15,8 @@ impl Default for FileTypes {
files: false, files: false,
directories: false, directories: false,
symlinks: false, symlinks: false,
sockets: false,
pipes: false,
executables_only: false, executables_only: false,
empty_only: false, empty_only: false,
} }

View file

@ -317,9 +317,9 @@ fn run() -> Result<ExitCode> {
file_types.executables_only = true; file_types.executables_only = true;
file_types.files = true; file_types.files = true;
} }
"e" | "empty" => { "e" | "empty" => file_types.empty_only = true,
file_types.empty_only = true; "s" | "socket" => file_types.sockets = true,
} "p" | "pipe" => file_types.pipes = true,
_ => unreachable!(), _ => unreachable!(),
} }
} }

View file

@ -390,13 +390,19 @@ fn spawn_senders(
if (!file_types.files && entry_type.is_file()) if (!file_types.files && entry_type.is_file())
|| (!file_types.directories && entry_type.is_dir()) || (!file_types.directories && entry_type.is_dir())
|| (!file_types.symlinks && entry_type.is_symlink()) || (!file_types.symlinks && entry_type.is_symlink())
|| (!file_types.sockets && filesystem::is_socket(entry_type))
|| (!file_types.pipes && filesystem::is_pipe(entry_type))
|| (file_types.executables_only || (file_types.executables_only
&& !entry && !entry
.metadata() .metadata()
.map(|m| filesystem::is_executable(&m)) .map(|m| filesystem::is_executable(&m))
.unwrap_or(false)) .unwrap_or(false))
|| (file_types.empty_only && !filesystem::is_empty(&entry)) || (file_types.empty_only && !filesystem::is_empty(&entry))
|| !(entry_type.is_file() || entry_type.is_dir() || entry_type.is_symlink()) || !(entry_type.is_file()
|| entry_type.is_dir()
|| entry_type.is_symlink()
|| filesystem::is_socket(entry_type)
|| filesystem::is_pipe(entry_type))
{ {
return ignore::WalkState::Continue; return ignore::WalkState::Continue;
} }