basename не принимает список путей (не говоря уже о том, что разделены символами новой строки), оно использует один путь (необязательно сопровождаемый суффиксом для удаления).
Кроме того, когда вы используете команду (например, echo) в обратных галочках, оболочка принимает вывод этой команды, разделяет ее на "слова", разделенные пробелами (обычно пробелы, табуляции и новые строки, но вы можете изменить их с помощью $IFS), расширяет любой он находит подстановочные знаки и передает результат всего этого другой команде (в данном случае basename). В результате, новые строки в выводе echo обрабатываются как просто больше пробелов между словами, а не передаются в basename вообще. Итак, эта команда:
basename `echo -e '/foo/bar \n /food/baz \n /oof/rab'`
эквивалентно:
basename "/foo/bar" "/food/baz" "/oof/rab"
... и, очевидно, когда basename получает три аргумента, как это, он печатает базовое имя каждого аргумента отдельно. Страница man для basename не документирует это поведение, поэтому в любом случае это ошибка, которая не выдает ошибку в этом случае.
Аналогично, эта команда:
basename `echo -e '/foo/bar \n /food/baz'`
эквивалентно
basename "/foo/bar" "/food/baz"
... но в этом случае поведение basename определено и совершенно иное - оно берет базовое имя первого аргумента, удаляет второй аргумент с его конца (если он совпадает) и печатает результат. "bar" не заканчивается на «/food/baz», поэтому он просто печатает "bar".
Кроме того, echo -e странно непереносима (даже между различными версиями OS X!). Ниже, я использовал Баш в $' ' строки , чтобы избежать последовательностей переведены.
Если вы хотите напечатать базовые имена списка путей, разделенных новой строкой, используйте цикл для запуска basename для каждого отдельно:
while read -r filepath; do
basename "$filepath"
done <<< $'/foo/bar \n /food/baz'
Или просто используйте sed для удаления до первой буквы "/" в каждой строке:
echo $'/foo/bar \n /food/baz \n /oof/rab' | sed 's@^.*/@@'