diff --git a/src/uu/tail/src/tail.rs b/src/uu/tail/src/tail.rs index 371f0e2ed..06d0e6fdb 100644 --- a/src/uu/tail/src/tail.rs +++ b/src/uu/tail/src/tail.rs @@ -477,7 +477,10 @@ where E: fmt::Debug, { if beginning { - iter.skip(count as usize).map(|r| r.unwrap()).collect() + // GNU `tail` seems to index bytes and lines starting at 1, not + // at 0. It seems to treat `+0` and `+1` as the same thing. + let i = count.max(1) - 1; + iter.skip(i as usize).map(|r| r.unwrap()).collect() } else { RingBuffer::from_iter(iter.map(|r| r.unwrap()), count as usize).data } diff --git a/tests/by-util/test_tail.rs b/tests/by-util/test_tail.rs index 1c025cf4c..dddbb9c31 100644 --- a/tests/by-util/test_tail.rs +++ b/tests/by-util/test_tail.rs @@ -348,3 +348,47 @@ fn test_negative_indexing() { fn test_sleep_interval() { new_ucmd!().arg("-s").arg("10").arg(FOOBAR_TXT).succeeds(); } + + +/// Test for reading all but the first NUM bytes: `tail -c +3`. +#[test] +fn test_positive_bytes() { + new_ucmd!() + .args(&["-c", "+3"]) + .pipe_in("abcde") + .succeeds() + .stdout_is("cde"); +} + + +/// Test for reading all bytes, specified by `tail -c +0`. +#[test] +fn test_positive_zero_bytes() { + new_ucmd!() + .args(&["-c", "+0"]) + .pipe_in("abcde") + .succeeds() + .stdout_is("abcde"); +} + + +/// Test for reading all but the first NUM lines: `tail -n +3`. +#[test] +fn test_positive_lines() { + new_ucmd!() + .args(&["-n", "+3"]) + .pipe_in("a\nb\nc\nd\ne\n") + .succeeds() + .stdout_is("c\nd\ne\n"); +} + + +/// Test for reading all lines, specified by `tail -n +0`. +#[test] +fn test_positive_zero_lines() { + new_ucmd!() + .args(&["-n", "+0"]) + .pipe_in("a\nb\nc\nd\ne\n") + .succeeds() + .stdout_is("a\nb\nc\nd\ne\n"); +}