Як надрукувати нові рядки у виведенні командного рядка

Дивно, але отримати комп’ютери, які дають людям читабельну продукцію, є непростим подвигом. З введенням стандартних потоків і, зокрема, стандартного виводу, програми отримали спосіб спілкуватися між собою, використовуючи текстові потоки. Але гуманізація та показ stdout - це інша справа. Технології впродовж усього обчислювального віку намагалися вирішити цю проблему, починаючи від використання символів ASCII на дисплеях відеокомп'ютерів до сучасних команд оболонки, таких як echoі printf.

Ці досягнення не були безперервними. Робота друку вихідних даних на терміналі загрожує примхами для навігації програмістів, що ілюструється оманливо нетривіальним завданням розширення послідовності виходу для друку нових рядків. Розширення заповнювача \nможе бути здійснено різними способами, кожен зі своєю унікальною історією та ускладненнями.

Використовуючи echo

Від появи в Multics до сучасної системи, схожої на Unix, echoзалишається звичним інструментом змусити ваш термінал сказати "Привіт, світ!" На жаль, суперечливі впровадження в операційних системах роблять його використання складним. Де echoв деяких системах автоматично розширюються послідовності екранування, для інших потрібна -eможливість зробити те ж саме:

echo "the study of European nerves is \neurology" # the study of European nerves is \neurology echo -e "the study of European nerves is \neurology" # the study of European nerves is # eurology

Через ці суперечності в реалізаціях echoвважається не портативним. Крім того, його використання разом із введенням користувачем порівняно легко пошкодити через атаку введення оболонки за допомогою підстановок команд.

У сучасних системах він зберігається лише для забезпечення сумісності з багатьма програмами, які все ще використовують його. Специфікація POSIX рекомендує використовувати printfв нових програмах.

Використовуючи printf

Починаючи з 4-го видання Unix, портативна printfкоманда, по суті, була новою та кращою echo. Це дозволяє використовувати специфікатори формату для гуманізації введення. Для інтерпретації зворотних косих рис керуючих послідовностями, використання %b. Послідовність символів \nзабезпечує вихід, що закінчується новим рядком:

printf "%b\n" "Many females in Oble are \noblewomen" # Many females in Oble are # oblewomen

Незважаючи на наявність printfдодаткових опцій, які роблять його набагато потужнішою заміною echo, ця утиліта не є надійною і може бути вразливою до неконтрольованої атаки рядкового формату. Для програмістів важливо забезпечити, щоб вони ретельно обробляли введені користувачем дані.

Введення нових рядків у змінні

З метою покращення переносимості серед компіляторів, стандарт ANSI C був створений в 1983 році. За допомогою цитування ANSI-C $'...', вихідні послідовності замінюються на виході відповідно до стандарту.

Це дозволяє нам зберігати рядки з новими рядками у змінних, які друкуються з інтерпретованими новими рядками. Ви можете зробити це, встановивши змінну, а потім викликавши її за printfдопомогою $:

puns=$'\number\narrow\nether\nice' printf "%b\n" "These words started with n but don't make $puns" # These words started with n but don't make # umber # arrow # ether # ice

Розширена змінна має одинарні лапки, які передаються буквально до printf. Як завжди, важливо правильно обробляти введені дані.

Бонусний раунд: розширення параметра оболонки

У своїй статті, що пояснює Bash і фігурні дужки, я розповів про магію розширення параметрів оболонки. Ми можемо використовувати одне розширення ${[email protected]}, для інтерпретації послідовностей екранування. Ми використовуємо специфікатор printf'' %sдля друку у вигляді рядка, і Eоператор правильно розширить послідовності екрану в нашій змінній:

printf "%s\n" ${[email protected]} # umber # arrow # ether # ice

Постійний виклик розмови по-людськи

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

Погана інтерполяція рядків може призвести до безглуздого виводу, а також створити вразливі місця безпеки, такі як атаки введення. Поки до наступної еволюції терміналу ми не будемо говорити в смайликах, найкраще звертати увагу при друкуванні вихідних матеріалів для людей.