Как заметили большинство других, «-n» интерпретируется буквально, если размещено где-нибудь, но сразу после echoкоманды.
Исторически UNIX-утилиты были такими: они искали параметры только сразу после имени команды. Вероятно, либо BSD, либо GNU стали первыми в более гибком стиле (хотя я могу ошибаться), так как даже сейчас POSIX указывает старый способ как правильный (см. Рекомендацию 9, а также man 3 getoptв системе Linux). В любом случае, хотя большинство утилит Linux в наши дни используют новый стиль, есть некоторые несогласные echo.
EchoЭто беспорядок, связанный со стандартами, поскольку к моменту появления POSIX в игре было по крайней мере две принципиально противоречивые версии . С одной стороны, у вас есть стиль SYSV, который интерпретирует символы с обратной косой чертой, но в остальном обрабатывает свои аргументы буквально, не принимая никаких опций. С другой стороны, у вас есть BSD-стиль, который рассматривает инициал -nкак особый случай и выводит буквально все остальное. А поскольку echoэто так удобно, у вас есть тысячи сценариев оболочки, которые зависят от того или иного поведения:
echo Usage: my_awesome_script '[-a]' '[-b]' '[-c]' '[-n]'
echo -a does a thing.
echo -b does something else.
echo -c makes sure -a works right.
echo -- DON\'T USE -n -- it\'s not finished! --
Из-за семантики «относиться ко всему буквально» невозможно даже добавить новую опцию, echoне ломая вещи. Если бы GNU использовала гибкую схему опций, ад был бы свободен.
Кстати, для лучшей совместимости между реализациями оболочки Bourne используйте printfвместоecho .
ОБНОВЛЕНО, чтобы объяснить, почему, echoв частности, не используются гибкие параметры.
echo -n "bar"дает "бар", в то время какecho "bar" -nдает "бар-н"