є труба ls така сама, як ls -1?


19

lsповертає висновок у декількох стовпцях, тоді як ls|catповертає байт-ідентичний вихід з ls -1для каталогів, які я пробував. Досі бачу ls -1відповіді, як ls -1|wc -l. Чи є колись причина віддати перевагу ls -1? Чому ...|catзмінюється вихід ls?


1
імена файлів можуть містити нові рядки, тож ви порахували б їх кілька разів ... замість цього ви можете це зробити posixly: n=0; for i in .* *; do ((n++)) ; done ; echo $n( відмініть . *, якщо ви не хочете рахувати їх). або: ls -1d ./.* ./* | grep '^\./' | wc -l (оскільки назви файлів не можуть містити '/')
Олів'є Дулак

3
lsвихід до терміналу зазвичай включає кольорові коди за замовчуванням. Для виводу на нетермінальний колір, як правило, вимкнено за замовчуванням. У GNU це --color={always,auto,never}IIRC. Якщо колір включений в один, а не в інший, то виводи можуть виглядати однаковими на екрані, але вони не є однаковими байтами (кольорові коди складають частину виводу ls).
CVn

@ MichaelKjörling Я думаю, ви повинні написати це як відповідь.
200_успіх

@ MichaelKjörling Це щось цікаве я не розглядав. Чи є загальний спосіб завжди передавати трубку так, як ніби виводиться на термінал, не запам'ятовуючи параметри терміналу для виводу кольорів та стовпців тощо?
rubystallion

@rubystallion Це звучить як гарне окреме запитання.
CVn

Відповіді:


26

lsперевіряє, чи буде вихід на термінал. Якщо вихід не збирається до терміналу, то -1це за замовчуванням. (Це може бути скасовано одним з -C, -mабо -xопцій.)

Таким чином, коли lsвикористовується в конвеєрі, і ви не перекрили його іншим варіантом, він lsбуде використовувати -1. Ви можете покластися на це, оскільки така поведінка вимагає POSIX

Специфікація POSIX

POSIX вимагає -1за замовчуванням кожен раз, коли вихід не збирається в термінал:

Специфікація POSIX :

Формат за замовчуванням повинен містити перелік одного запису на рядок до стандартного виводу; винятки становлять термінали або коли вказано один із параметрів -C, -m або -x. Якщо висновок призначений для терміналу, формат визначається реалізацією.

Ці три варіанти, які змінюють формат одноколонного за замовчуванням:

-C
Запишіть висновки багатотекстових стовпців із записами, відсортованими стовпцями, відповідно до послідовності згортання. Кількість текстових стовпців та символів роздільника стовпців не визначено, але їх слід адаптувати до характеру пристрою виводу. Ця опція вимикає вихід довгого формату.


формат виходу потоку; список імен шляхів на всій сторінці, розділених символом <comma>, а потім символом <space>. Використовуйте символ <newline> як термінатор списку та після послідовності роздільника, коли в рядку немає місця для наступного запису списку. Ця опція вимикає вихід довгого формату.

-x
Те саме, що і -C, за винятком того, що висновок мультитекстового стовпця виробляється із записами, відсортованими в стовпцях, а не вниз. Ця опція вимикає вихід довгого формату.

Документація GNU

З посібника GNU :

'-1'
'--format = одноколонка'
Перерахуйте один файл у рядку. Це значення за замовчуванням для ls, коли стандартний вихід не є терміналом . Дивіться також параметри -b та -q для придушення прямого виводу символів нового рядка в імені файлу. [Наголос додано]

Приклади

Створимо три файли:

$ touch file{1..3}

Коли вихід надходить до терміналу, GNU lsвирішує використовувати формат у декількох стовпцях:

$ ls
file1  file2  file3

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

$ ls | cat
file1
file2
file3

Три винятки, які переосмислюють поведінку однієї колонки за замовчуванням, -mстосуються розділених комами, -Cсортування стовпців та -xвідсортованих стовпців:

$ ls -m | cat
file1, file2, file3
$ ls -C | cat
file1  file2  file3
$ ls -x | cat
file1  file2  file3

"POSIX вимагає -1, як за замовчуванням, коли вихід йде в термінал:" ... але цитата вказує, що він вимагається -1як за замовчуванням, за винятком випадків, коли вихід надходить до терміналу (або інших умов)
muru

@muru Дякую за те, що це зробив! Відповідь оновлено.
John1024

Що ж, кожна хмара має срібну підкладку. Оскільки ваша відповідь була прийнята ще до моєї публікації, я отримав прикольну шапку для піци!
G-Man каже: "Відновіть Моніку"

@ G-Man Дуже добре. І, гарний капелюх це!
John1024

9
  • Чому трубопроводи стандартного виходу змінюють поведінку ls? Тому що він був сконструйований таким чином. Специфікація POSIX каже:

    Формат за замовчуванням повинен містити перелік одного запису на рядок до стандартного виводу; виключення є терміналами або коли один з -C, -mабо -xопції вказується. Якщо висновок призначений для терміналу, формат визначається реалізацією.

    що насправді неоднозначно щодо поведінки за замовчуванням (коли не визначено параметром типу -lабо -1) з виходом до терміналу, і документація GNU Coreutils говорить

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

    Таким чином, ви можете бачити, що вихід у файл буде діяти так само, як і вихід у трубу; тобто один запис на рядок, як би -1визначений.

  • Чому він був розроблений саме так? Це точно не можливо дізнатися (якщо хтось не зможе знайти якісь примітки дизайну), але я думаю:
    • Коли lsйдеться на термінал, він очікує, що людина дивиться на вихід. Люди вважають за краще отримувати інформацію в мінімально необхідній кількості рядків, тому матеріал не прокручує екран.
    • Коли lsпишеш на трубу, очікує, що інша програма прочитає вихід. Програмі набагато простіше читати дані, що мають одне значення на рядок, ніж намагатися розбирати стовпці (оскільки назви файлів можуть містити пробіли).
  • Чи є коли-небудь причина віддавати перевагу, ls -1 коли ви пишете у файл чи трубку? Ні.

-4

Під час передачі ls ls не може визначити, скільки стовпців фактично має консоль (незалежно від правої команди). Тож ls просто робить це на власний вибір, або, інакше кажучи, така поведінка нестабільна і може змінюватися в наступних версіях.

На відміну від цього, він ls -1був створений з метою підрахунку або сценаріїв загалом, тому його поведінка стабільна.


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