Динамічно обрізати ширину лінії відтінку в Bash


9

Останнім часом я експериментую з psкомандою, а іноді довгі шляхи перебираються на наступний рядок (або два) і ускладнюють читання. Я хочу передати psвихід в іншу програму, щоб обмежити вихід на xкількість символів.

Ось що я маю поки що, але це працює не зовсім правильно:

ps aux | cut -c1-$(stty size | cut -d' ' -f2)

$(stty size | cut -d' ' -f2)оцінює 167, але, здається, не є дійсним для cut.

Чи є спосіб змусити цей тип синтаксису працювати в bash?


Ця робота для мене. Чи можете ви надати деякий вихід?
cuonglm

де динамічна частина? Ви хочете різної довжини для певних умов? Схоже, ви хочете обмежити весь вихід на одну максимальну довжину

@awk_FTW Залежно від ситуації, у мене є різні налаштування вікна. На повноекранному екрані моя ширина становить 167. Але для інших розмірів мені потрібно буде менше. Ось чому я хочу зателефонувати ssty, щоб отримати розмір.
сочевиця

Спробуйтеtput rmam; ps aux
Stéphane Chazelas

Деякі оболонки подобається zsh, ksh93або bashзберігати термінал в ширину$COLUMNS
Stéphane Chazelas

Відповіді:


5

Наступні роботи:

ps aux | cut -c1-$(stty size </dev/tty | cut -d' ' -f2)

Це також працює:

v=$(stty size | cut -d' ' -f2) ; ps aux | cut -c1-$v

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

Є ще інший варіант. Хоча sttystdin і stdout обидва перенаправлені у вищезазначених командах, його stderr немає: він все ще вказує на термінал. Як не дивно, sttyвін також буде працювати, якщо він буде наданий більш жорстким як його вклад:

ps aux | cut -c1-$(stty size <&2 | cut -d' ' -f2)

Справді, так і є! Це саме те, що я шукав. Цікаво, чому ти в кінці додав tee tt?
сочевиця

@lentils На жаль, teeдодано під час налагодження. Зараз її немає.
John1024

Що стосується <& 2? Я ніколи раніше не бачив цієї нотації.
сочевиця

@lentils У оболонці файли пронумеровані. Нуль відноситься до стандартного вводу, один до стандартного виводу, а два - до стандартної помилки. Вираз <&2означає, що отримаєте свій внесок із стандартної помилки.
John1024

1
sttyотримує налаштування терміналу, відкритого на його stdin (ви робите, stty < /dev/other-ttyщоб отримати налаштування іншого терміналу, наприклад). Тож не дивно, що він не спрацює, якщо його stdin - це труба або це <&2працює.
Стефан Шазелас

8

Деякі оболонки подобається zsh, bashабо mkshавтоматично встановити $COLUMNSзмінну ширину терміналу, так що вам не потрібно посилатися sttyтут.

Усі реалізації psя намагався підтримувати той нестандартний синтаксис (тип BSD), запитуючи термінальну ширину самостійно. Я здивований, що ваша ні. Я очікую, що він буде розглядати зміст змінної COLUMNS середовища .

Отже, ви можете зробити:

export COLUMNS; ps aux

Якщо ні,

ps aux | cut -c"1-$COLUMNS"

Ви також можете сказати своєму терміналу не перетворювати лінії:

tput rmam
ps aux

4

Ви також можете обробити psвихід трохи краще.

ps --width ${n:-$COLUMNS} ${opts} #set ps terminal width

ps -ww ${opts} #no word wrap

ps -o ${only_interesting_output} ${opts} #trim output

Це дозволить psпроаналізувати свій вихід на ваші технічні характеристики за потребою.

Звичайно, якщо ви не переказуєте слова, то у вас виникає проблема з відсутністю інформації. Вам справді потрібно все це для всіх процесів? Відкрийте його в пейджері, якщо так:

ps ww ${opts} | $PAGER

Якщо ні, вкажіть, що ви хочете бачити:

ps -o args= -p $pid

Ви також можете чітко повідомити psпро свій термінал --width:

man ps

...

w Широкий вихід. Використовуйте цю опцію двічі для необмеженої ширини.

-w Широкий вихід. Використовуйте цю опцію двічі для необмеженої ширини.

--width n Встановити ширину екрана.

Ця --widthріч працює саме на запитувані вами характеристики, не залучаючи будь-яких додаткових фільтрів або допоміжних процесів (які, ймовірно, -auxще більше захаращують ваш вихід). І, $COLUMNSяк показано вище, і як вказує Стефан, це навіть буде динамічно працювати.

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

-oUtput операнда я згадав вище дозволяю фільтрувати стовпці , які psвідображаються, а при додаванні =розпаювання ви можете навіть назвати колонки , як вам завгодно. Я залишаю завдання порожнім і вручаю йому цільову -pобробку, $pidтому єдиним результатом з psусіх є $pidім'я команди та її argsпри виклику. І -oледь не дряпає поверхню того, як ви можете визначити, що psбуде чи не буде відображатися. Це я б рекомендував вам взяти, особливо через:

man ps

... 

Щоб побачити кожен процес у системі, що використовує синтаксис BSD:

ps ax

ps axu

Щоб надрукувати дерево процесу:

ps -ejH

ps axjf

Щоб отримати інформацію про теми:

ps -eLf

ps axms

Щоб отримати інформацію про безпеку:

ps -eo euser,ruser,suser,fuser,f,comm,label

ps axZ

ps -eM

Щоб побачити кожен процес, що працює як root (реальний та ефективний ідентифікатор) у форматі користувача:

ps -U root -u root u

Щоб побачити кожен процес у визначеному користувачем форматі:

ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm

ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm

ps -Ao pid,tt,user,fname,tmout,f,wchan

Роздрукуйте лише ідентифікатори процесу syslogd:

ps -C syslogd -o pid=

Роздрукуйте лише назву PID 42:

ps -p 42 -o comm=

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