Чому відлуння "бар" -n відрізняється від відлуння - від "бар"?


10

Порівняйте

echo -n "bar"

з

echo "bar" -n

Перший робить те, що, на мою думку, потрібно робити (друкує "смужку" без нового рядка), а другий - ні. Це помилка чи за дизайном? Чому він відрізняється від багатьох програм кліпа тим, що ви не можете переміщувати параметри? Наприклад, tail -f /var/log/messagesточно такий же, як tail /var/log/messages -f. Я іноді роблю останнє, коли забуваю, що хотів першого, тому що внутрішньо параметри та аргументи переставляються, як правило, за допомогою getopt .

Оновлення: так, я спочатку нервував своє запитання. Я видалив нервову особу, яку вам доведеться переглядати історію, щоб мати відповідь на деякі сенси.


3
З того, що я бачу, різниця є відразу. echo -n "bar"дає "бар", а echo "bar" -nдає "bar -n"
phunehehe

Відповіді:


18

Як зауважили більшість інших, "-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 скоріше використовуйтеprintfecho .

ОНОВЛЕНО, щоб пояснити, чому, echoзокрема, не використовуються гнучкі варіанти.


upvote, оскільки ви єдиний, хто згадує, що це очікувана поведінка щодо отримання.
Джеффрі Бачелет

@jander Чому відлуння є "утриманням"? Я думаю, що це gnu coreutil?
ксенотерацид

@xeno: я оновив свою відповідь. В основному, GNU не хотіла ламати речі.
Джандер

1
Беручи варіанти після першого НЕ-опції специфічний для GNU утиліт і програм з використанням GNU Libc «s Getopt об'єктів. Користувач завжди може отримати зворотно сумісну поведінку, встановивши змінну середовища POSIXLY_CORRECT.
Жиль "ТАК - перестань бути злим"

1
Для конкретного випадку echoтакож існують реалізації, які розпізнають -eабо -Eє опціями. Для переносимості не починайте з -або використовувати щось подібне printf %s -e.
Жил "ТАК - перестань бути злим"

9

Інші відповіді доходять до того, що ви можете переглядати сторінку людини, щоб побачити, що -n стає частиною рядка, що лунає наголосом. Однак я просто хочу зазначити, що це легко дослідити без md5sum і робить те, що відбувається трохи менш виразним.

[11:07:44][dasonk@Chloe:~]: echo -n "bar"
bar[11:07:48][dasonk@Chloe:~]: echo "bar" -n
bar -n

3
+1 точно. Якщо трубопровід не виконує те, що ви очікували, протестуйте кожну деталь окремо.
Мікель

6

Ух, всі пояснення є тривалими.

Це так просто:

-n є варіантом, якщо він з’являється перед рядком, інакше це лише інший рядок, який повинен бути відлуненим.

Видаліть | md5sum і ви побачите, що вихід відрізняється.


5

З простого огляду, це не помилка за дизайном ...

echo "bar" -n | md5sum

a3f8efa5dd10e90aee0963052e3650a1

Спробуйте цю команду для себе:

echo "bar -n" | md5sum

Ви помітите, що отриманий md5 є

a3f8efa5dd10e90aee0963052e3650a1

Ви просто змішали використання -n в ехо.

У вашому першому зразковому коді

echo -n "bar" | md5sum

-n використовується, щоб сказати НЕ, щоб ставити новий рядок після цього відлуння.

Ваш другий зразок

echo "bar" -n | md5sum

трактує -n як буквальний текст.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.