diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index 3d590e1bf..62fcfceda 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -629,7 +629,10 @@ fn read_files_from(file_name: &str) -> Result, std::io::Error> { show_error!("{file_name}:{line_number}: invalid zero-length file name"); set_exit_code(1); } else { - paths.push(PathBuf::from(String::from_utf8_lossy(&path).to_string())); + let p = PathBuf::from(String::from_utf8_lossy(&path).to_string()); + if !paths.contains(&p) { + paths.push(p); + } } } diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 955759cb8..9e4622c31 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -1010,6 +1010,21 @@ fn test_du_files0_from() { .stdout_contains("testdir"); } +#[test] +fn test_du_files0_from_ignore_duplicate_file_names() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + let file = "testfile"; + + at.touch(file); + at.write("filelist", &format!("{file}\0{file}\0")); + + ts.ucmd() + .arg("--files0-from=filelist") + .succeeds() + .stdout_is(format!("0\t{file}\n")); +} + #[test] fn test_du_files0_from_with_invalid_zero_length_file_names() { let ts = TestScenario::new(util_name!()); @@ -1046,6 +1061,23 @@ fn test_du_files0_from_stdin() { .stdout_contains("testfile2"); } +#[test] +fn test_du_files0_from_stdin_ignore_duplicate_file_names() { + let ts = TestScenario::new(util_name!()); + let at = &ts.fixtures; + let file = "testfile"; + + at.touch(file); + + let input = format!("{file}\0{file}"); + + ts.ucmd() + .arg("--files0-from=-") + .pipe_in(input) + .succeeds() + .stdout_is(format!("0\t{file}\n")); +} + #[test] fn test_du_files0_from_stdin_with_invalid_zero_length_file_names() { new_ucmd!()