Вихід з ls має нові рядки, але відображається в одному рядку. Чому?


41

Я думаю, що я, можливо, не помічаю відносно принципового моменту щодо оболонки. Виведення з команди ls за замовчуванням відокремлює вихід з новими рядками, але оболонка відображає вихід у одному рядку.

Хтось може мені це пояснити? Я завжди припускав, що вихід просто розділений пробілами, але тепер, коли я бачу, як результат відокремлений новими рядками, я очікую, що результат буде відображатися в окремих рядках.

Приклад:

cpoweradm@debian:~/lpi103-4$ ls text*
text1  text2  text3

od показує, що вихід відокремлений новими рядками:

cpoweradm@debian:~/lpi103-4$ ls text* | od -c
0000000   t   e   x   t   1  \n   t   e   x   t   2  \n   t   e   x   t
0000020   3  \n
0000022

Якщо присутні нові рядки, то чому виведення не відображається як:

text1 
text2
text3

Відповіді:


44

Коли ви трубите вихід, lsдіє по-іншому.

Цей факт приховано в інформаційній документації :

Якщо стандартний вихід є термінальним, то висновок знаходиться у стовпцях (відсортованих по вертикалі), а контрольні символи виводяться як знаки запитання; в іншому випадку виводиться список по одному на рядок, а контрольні символи виводяться як є.

Щоб довести це, спробуйте запустити

ls

і потім

ls | less

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

ls -1

( -1це номер один)

Або ви можете примусити ls | lessвиводити в стовпці, запустивши

ls -C

( -Cє капіталом C)


6
@theconnorpower: це дуже специфічно для ls. Це корисно, але явно непослідовно і дивно. Але зауважте, що деякі команди, що створюють кольоровий вихід, знімуть кольори і при трубопроводі.
Мікель

5
@theconnorpower: Дрібниці: Винахідники Unix продовжували писати План9. У Plan9 lsзавжди друкується по одному на рядок і lcзавжди друкується у стовпцях.
Мікель

2
@theconnorpower: Є також програми, які читають розмір терміналу і відповідно коригують їх вихід, наприклад, Debian dpkg -lбуде використовувати всю ширину екрана, але якщо він друкується на трубу, він передбачає, що термінал має ширину 80 стовпців , і скорочує висновок, щоб при необхідності його підходити.
Мікель

1
@Mikel Цікаво почути різниці ls / lc у Плані9. Дякую за детальну відповідь.
zod90

1
Як програма може визначити, чи буде її вихід перенаправлений у файл чи збирається він у оболонку?
user2820379

4

Ваше відкриття підкреслює першопричину, чому синтаксичний аналіз результатів lsзавжди є поганою ідеєю. Повне пояснення див. У Вікі Грега .

Подумайте про свою проблему навпаки. Ви помітили, що ls інколи робить, а іноді не друкує нові рядки між його вихідними. Для використання в сценаріях або коли вимушений -1прапор, це робить. Один новий рядок в кінці кожного файлу. Що немає гарантії, що кожен новий рядок представляє нове ім'я файлу . Насправді, якщо ім'я файлу містить сам новий рядок, вихід ls буде абсолютно непроаналізованим. Розглянемо ці імена файлів:

file1
file2\nfile3
file4

Коли ви будете ls -1мати каталог з цим у ньому, ви отримаєте щось таке:

file1
file2
file3
file4

Ви природно не припустили, що було чотири файли? Як і будь-які сценарії, які аналізують вихід ls. Насправді є три файли, один із хитрих назв, але ви не зможете це зрозуміти з виводу ls. *

* Якщо ви не використовували -lпрапор і не помітили, що вихід був захищений, але ваші сценарії все одно задушаться.


3
Якщо вам дійсно доведеться проаналізувати вихід ls, -bопція може допомогти. Це перетворює новий рядок у \nтощо
Мікель
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.