diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index 19f123a02..de65622a3 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -218,17 +218,29 @@ pub fn uumain(args: impl uucore::Args) -> i32 { return 0; } - if matches.free.is_empty() { - usage(&opts); - return 1; - } - let dflag = matches.opt_present("d"); let cflag = matches.opts_present(&["c".to_owned(), "C".to_owned()]); let sflag = matches.opt_present("s"); let tflag = matches.opt_present("t"); let sets = matches.free; + if sets.is_empty() { + show_error!( + "missing operand\nTry `{} --help` for more information.", + NAME + ); + return 1; + } + + if !(dflag || sflag) && sets.len() < 2 { + show_error!( + "missing operand after ‘{}’\nTry `{} --help` for more information.", + sets[0], + NAME + ); + return 1; + } + if cflag && !dflag && !sflag { show_error!("-c is only supported with -d or -s"); return 1; diff --git a/tests/by-util/test_tr.rs b/tests/by-util/test_tr.rs index 06cf88ff6..cc8e22991 100644 --- a/tests/by-util/test_tr.rs +++ b/tests/by-util/test_tr.rs @@ -116,3 +116,23 @@ fn test_truncate_with_set1_shorter_than_set2() { .run() .stdout_is("xycde"); } + +#[test] +fn missing_args_fails() { + let (_, mut ucmd) = at_and_ucmd!(); + let result = ucmd.run(); + + assert!(!result.success); + assert!(result.stderr.contains("missing operand")); +} + +#[test] +fn missing_required_second_arg_fails() { + let (_, mut ucmd) = at_and_ucmd!(); + let result = ucmd + .args(&["foo"]) + .run(); + + assert!(!result.success); + assert!(result.stderr.contains("missing operand after")); +}