Який хороший приклад з'єднання команд разом?


33

Якщо ви допомагали комусь вивчити поняття "Труби" в командному рядку, який приклад ви б використовували? Приклад, який насправді з’явився:

cat whatever.txt | less

Я відчуваю, що це не найкращий приклад, а саме тому, що є лише один крок. Чим корисне, але фундаментальне використання |?

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


3
Ваш приклад насправді не настільки гарний - це в основному номінація на нагороду за марну користь.
maxschlepzig

@maxschlepzig Не те, що ми помиляємось, але ви теж не дуже корисні; вам це не потрібно cat, оскільки це less whatever.txtпрацює чудово.
Бора М. Альпер

Відповіді:


34

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

Проблема

Скажімо, команда conkyперестала відповідати на моєму робочому столі, і я хочу її вбити вручну. Я трохи знаю Unix, тому знаю, що мені потрібно виконати команду kill <PID>. Для того , щоб витягти PID, я можу використовувати psабо topчи будь інший інструмент , моє розподіл Unix дав мені. Але як я можу це зробити за допомогою однієї команди?

Відповідь

$ ps aux | grep conky | grep -v grep | awk '{print $2}' | xargs kill

ВИСНОВОК: Ця команда працює лише в певних випадках. Не копіюйте та не вставляйте його у свій термінал і не починайте його використовувати, це може вбити процеси без сумніву. Швидше навчитися її будувати .

Як це працює

1- ps aux

Ця команда виведе список запущених процесів та деяку інформацію про них. Цікава інформація полягає в тому, що він виведе PID кожного процесу у своєму другому стовпці. Ось витяг із результату команди в моєму полі:

$ ps aux
 rahmu     1925  0.0  0.1 129328  6112 ?        S    11:55   0:06 tint2
 rahmu     1931  0.0  0.3 154992 12108 ?        S    11:55   0:00 volumeicon
 rahmu     1933  0.1  0.2 134716  9460 ?        S    11:55   0:24 parcellite
 rahmu     1940  0.0  0.0  30416  3008 ?        S    11:55   0:10 xcompmgr -cC -t-5 -l-5 -r4.2 -o.55 -D6
 rahmu     1941  0.0  0.2 160336  8928 ?        Ss   11:55   0:00 xfce4-power-manager
 rahmu     1943  0.0  0.0  32792  1964 ?        S    11:55   0:00 /usr/lib/xfconf/xfconfd
 rahmu     1945  0.0  0.0  17584  1292 ?        S    11:55   0:00 /usr/lib/gamin/gam_server
 rahmu     1946  0.0  0.5 203016 19552 ?        S    11:55   0:00 python /usr/bin/system-config-printer-applet
 rahmu     1947  0.0  0.3 171840 12872 ?        S    11:55   0:00 nm-applet --sm-disable
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:38 conky -q

2- grep conky

Мене цікавить лише один процес, тому я використовую, grepщоб знайти запис, відповідний моїй програмі conky.

$ ps aux | grep conky
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q
 rahmu     3233  0.0  0.0   7592   840 pts/1    S+   16:55   0:00 grep conky

3- grep -v grep

Як ви бачите на кроці 2, команда psвиводить grep conkyпроцес у своєму списку (зрештою, це запущений процес). Для того, щоб його відфільтрувати, я можу запустити grep -v grep. Параметр -vповідомляє grepвідповідати всі рядки, виключаючи ті, що містять візерунок.

$ ps aux | grep conky | grep -v grep
 rahmu     1948  0.2  0.0 276000  3564 ?        Sl   11:55   0:39 conky -q

NB: Я хотів би знати спосіб виконання кроків 2 і 3 в одному grepдзвінку.

4- awk '{print $2}'

Тепер, коли я виділив свій цільовий процес. Я хочу отримати його PID. Іншими словами, я хочу отримати 2-е слово результату. На щастя для мене, більшість (усіх?) Сучасних об'єднань нададуть певну версію awk, мову сценарію, яка творить чудеса з табличними даними. Наше завдання стає настільки ж простим, як print $2.

$ ps aux | grep conky | grep -v grep | awk '{print $2}'
 1948

5- xargs kill

У мене є ПІД. Все, що мені потрібно, - це передати це kill. Для цього я буду використовувати xargs.

xargs killпрочитає з входу (в нашому випадку з труби), сформує команду, що складається з kill <items>(що <items>б вона не читала з вводу), а потім виконає створену команду. У нашому випадку це буде виконано kill 1948. Місія виконана.

Заключні слова

Зауважте, що залежно від того, яку версію unix ви використовуєте, деякі програми можуть поводитись трохи інакше (наприклад, psможуть виводити PID у стовпці $ 3). Якщо щось здається неправильним чи іншим, прочитайте документацію вашого постачальника (а краще, manсторінки). Також будьте обережні, оскільки довгі труби можуть бути небезпечними. Не робіть жодних припущень, особливо при використанні таких команд як killабо rm. Наприклад, якщо був інший користувач з ім'ям «conky» (або «Aconkyous»), моя команда може також вбити всі його запущені процеси!

Що я кажу, будьте обережні, особливо для довгих труб. Завжди краще будувати його інтерактивно, як ми тут, ніж робити припущення і пізніше шкодувати.


NB: Я хотів би знати спосіб виконання кроків 2 і 3 в одному греп-дзвінку. -> grep "conky -q" :)
Wolfy

3
Насправді це поганий приклад, як ви могли просто зробитиkill $(pgrep conky)
Патрік

5
Я знаю, що це пізно, але ви можете спростити це ще більшеpkill conky
strugee

2
"" "NB: Я хотів би знати спосіб зробити кроки 2 і 3 в одному виклику грепу." "" Замість "aux" використовуйте "-pid, comm" - це також більш портативно, оскільки це POSIX -комплікація. Таким чином процес grep відображатиметься як "grep" замість "grep conky", тому він не відповідає собі.
Випадково832

2
NB: Я хотів би знати спосіб виконання кроків 2 і 3 в одному grepдзвінку. grep [c]onkyце те, що ви шукаєте.
AlexT

15

Моя улюблена така:

youtube-dl $1 -q -o - | ffmpeg -i - $2

завантажує відео з даної URL-адреси youtube, що передається, $1і виводить його у вигляді файлу, який надає $2. Зверніть увагу, як файл тихо -qвиводиться в STDOUT -o -, передається в ffmpeg і використовується як вхід там -i -.

Особливо для Linux-новачків це може бути прикладним прикладом, чому командний рядок може бути корисним та полегшити справи, ніж використання інструментів GUI. Я не впевнений, скільки часу знадобиться завантажити відео з YouTube та перетворити його звук в mp3. Вищенаведений рядок може зробити це за кілька секунд.


3
youtube-dl має можливість зберігати лише аудіо. Моя звичайна команда така, де URL-адреси надходять на stdin : youtube-dl --extract-audio --audio-format mp3 -a -. Ще класний приклад, але є простіші способи зробити це. (Це закликає ffmpeg внутрішньо.)
Brigand

3
@FakeRainBrigand: Ха-ха, добре знати! Але я отримав альтернативу, яку не слід вбудовувати: youtube-dl $1 -q -o - | mplayer -безпосередньо відтворює відео всередині mplayer. Я використовую цю команду зі свого ноутбука, щоб сказати своєму серверу (який підключений до телевізора) для відтворення відео. Я повинен додати, -display :0.0 -geometry 400x300+1200+200щоб вікно mplayer відображалося на правильному екрані.
Baarn

9

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

Тож я б сказав, що труби - це клей для збирання декількох будівельних блоків (різних інструментів UNIX) разом. Як сказав Ульріх, sortі uniqце звичайна строфа.

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

Тоді ви можете показати, як lynx --dump --listonlyотримується список посилань, як grepможна фільтрувати посилання, що закінчуються .pdf, як colrmчи sedможна було позбутися від цифр, що lynxзалишаються до кожної URL-адреси, як sortі як uniqможна позбутися дублікатів, і нарешті, як wget -i -можна використовувати для отримання файли ( --waitзвичайно, використовуючи ніжність на сервері).

Боюся, це складний приклад. З іншого боку, це може допомогти показати потужність труб, коли ви просто трубите її, і оболонка запустить все це відразу.


2
Ви також можете використовувати sort -uв GNU coreutils .
Teresa e Junior

2

Я точно не знаю про хороше, але проходження трубопроводів grepповинно бути одним із найпоширеніших застосувань, можливо, після цього wc -l. (Так, grepє маловідомий -cперемикач.)

Ще одна загальна строфа - | sort | uniqхоча б тому, що uniqвимагає сортування її введення.


Більшість людей вважає ... | sort -uза краще, якщо вони доступні!

2

Не те, що вам потрібно для цього прикладу, але:

$ ps aux | grep -v grep | grep conky

... повернення порядку грепсів зберігає забарвлення, але МНОГО менш ефективне. імовірно, у великих списках колір не має значення.

Також ця веб-сторінка пропонує:

https://stackoverflow.com/questions/9375711/more-elegant-ps-aux-grep-v-grep

> Johnsyweb відповів 21 лютого '12 о 10:31
> Звичайна хитрість така:
> ps aux | grep '[t] erminal'
> Це буде відповідати рядкам, що містять термінал, який "grep" [t] erminal "не робить!
> Він також працює на багатьох ароматах Unix.

... але це не спрацює, якщо ви шукаєте одну букву (наприклад, процес "X").


2

Зрештою, я ділюсь цим безладом онлайнера, який я зробив близько півтора років тому ...

while read in; do host "$in"; done < sites.txt | grep -iv "GOOGLE" | grep -E '1\.2\.3\.4|5\.6\.7\.8' | sed -e 's/has\ address\ 216.70.91.72//' | sed -e 's/has\ address\ 94.23.33.92//' | while read sites; do curl -sL -w "%{http_code} %{url_effective}\\n" "$sites" -o /dev/null; done | grep -ivE '4.*|5.*' | sed -e 's/200//' | sed -e 's/HTTP/http/'

Це ...

  1. Читає сайти.txt
  2. Запускається "хост" на кожному (заднім числом, dig + short зробив би це на тону простіше)
  3. Видаляє рядки, які містять "GOOGLE" - це записи mx
  4. Отримує лінії, які мають один з двох IP-адрес
  5. Отримує код коду статусу http для кожного сайту у списку
  6. Видаляє сайти, які повертаються 4xx або 5xx
  7. Знімає "200" з сайтів, які повернули це
  8. Замінює "HTTP" на "http" - суто естетичний, без реальних причин.

Це могло бути зроблено набагато краще за допомогою одного сценарію Python.


Ага ... я не впевнений, що це був би найчистіший і найпростіший приклад пояснення трубопроводу
новонародженому

2
Моє запитання, яке його призначення?
ADTC

У мене був файл, повний доменів, і мені потрібно було перевірити, чи знаходяться вони на одному з моїх двох серверів (що я, на жаль, "успадкував"). Це читає файл, робить "хост" і очищає цей вихід, а потім просто робить запит, щоб перевірити, чи повертає він помилку 4xx або 5xx. Якби це було, то він би відкинув домен; якщо ні, він виводить їх, і я поміщаю його в інший файл.
Засмажка

1

Це перше, що мені прийшло в голову ...

mysqldumpце консольний додаток, який надсилає дані, схему та необов'язково процедури та функції в stdout. Зазвичай він перенаправляється у файл для резервного копіювання.

mysqldump <options> > mydb.dump

Це дасть вам нестиснений сценарій sql. Щоб заощадити місце, ви можете стиснути його за допомогою bzip2.

bzip2 mydb.dump

Або ви можете зробити обидва в один крок:

mysqldump <options> | bzip2 > mydb.dump.bz2

У цьому прикладі вище, stdout з mysqldumpпередається на bzip2, після чого його вихід буде переспрямований у файл.


1
Додайте перевернуту операцію теж: bzcat mydb.dump.bz2 | mysql <options>.
манатурка

1

Ось приклад, який я використовую в своїй роботі декількох труб в одній команді. Для цього використовується gawk для пошуку загального журналу запитів MySQL ($ OFILE) та пошуку будь-яких відхилених входів. Потім він сортує цей список за назвою, передає цей список до uniq, який підраховує події, а потім труби він сортує останній раз, щоб сортувати відлічений список за числовим числом ...

gawk '{ for (x=1;x<=NF;x++) if ( $x~"Access" && $(x+4)~".*@.*") print $(x+4)}' $OFILE | sort | uniq -c | sort -n

1

Труби найкраще працюють з фільтрами та перекладачами

find /usr/bin/ |                #produce 
sed 's:.*/::'  |                #translate: strip directory part
grep -i '^z'   |                #filter   : select items starting with z
xargs -d '\n' aFinalConsumer    #consume  

Таким чином, дані можуть переходити з однієї програми в іншу буферною, і в жоден момент всі дані не повинні бути в пам'яті одразу.


0

cat filename | less це жахливе використання трубопроводів, оскільки ви просто можете це зробити less filename

Ось приклад піпсів, які я використовую щодня (але це також може бути поганим прикладом): ls -la | more -c

Відповіді Скотта Гофмана та Нісг є кращими прикладами.



0

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

du -m| sort -n| less

Sortiert nach Ordnergrösse


0

Ось приклад, який я використовував для встановлення змінної DISPLAY, коли xauth не був варіантом ...

export DISPLAY=\`who am i |awk '{print $NF}' | sed 's/[()]//g'`":0.0"

Перша команда отримує необхідні дані, тобто ім'я хоста або IP. Друга команда отримує саме ті дані (останнє поле). Нарешті, остання команда знімає дужки з даних.


0

Командний конвеєр ви можете використовувати де завгодно, якщо ви вважаєте, що вихід першої команди може подаватися як вхід до наступної.

Приклади.

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

приклад кота txt | grep {some_line} | awk {some_command}

  1. Працюючи з процесом, ви можете використовувати трубопроводи для надсилання команд для вбивства процесу.

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

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