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.
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`.
- 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
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.
## Bugfixes

4
doc/fd.1 vendored
View File

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

View File

@ -228,11 +228,15 @@ pub fn build_app() -> App<'static, 'static> {
"executable",
"e",
"empty",
"s",
"socket",
"p",
"pipe",
])
.hide_possible_values(true)
.help(
"Filter by type: file (f), directory (d), symlink (l),\nexecutable (x), \
empty (e)",
empty (e), socket (s), pipe (p)",
)
.long_help(
"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 \
'l' or 'symlink': symbolic links\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(

View File

@ -4,7 +4,7 @@ use std::ffi::OsStr;
use std::fs;
use std::io;
#[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 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"))]
pub fn osstr_to_bytes(input: &OsStr) -> Cow<[u8]> {
use std::os::unix::ffi::OsStrExt;

View File

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

View File

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

View File

@ -390,13 +390,19 @@ fn spawn_senders(
if (!file_types.files && entry_type.is_file())
|| (!file_types.directories && entry_type.is_dir())
|| (!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
&& !entry
.metadata()
.map(|m| filesystem::is_executable(&m))
.unwrap_or(false))
|| (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;
}