Каков хороший пример команд трубопроводов?

Если вы помогли кому-то узнать концепцию труб в командной строке, какой пример вы бы использовали? Пример, который действительно появился, был следующим:

cat whatever.txt | less 

Я чувствую, что это не лучший пример, а именно потому, что есть только один шаг. Что хорошего, но фундаментальное, использование | ?

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

Я собираюсь провести вам несколько сложный пример, основанный на сценарии реальной жизни.

проблема

Скажем, команда 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 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. Другими словами, я хочу получить второе слово вывода. К счастью для меня, большинство (все?) Современных устройств предоставят некоторую версию 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). Если что-то кажется неправильным или другим, прочитайте документацию своего поставщика (или, лучше, страницы руководства). Также будьте осторожны, поскольку длинные трубы могут быть опасными. Не делайте никаких предположений, особенно при использовании таких команд, как kill или rm . Например, если бы был еще один пользователь с именем conky (или «Aconkyous»), моя команда также может убить все его запущенные процессы!

То, что я говорю, очень осторожно, особенно для длинных труб. Всегда лучше строить его интерактивно, как мы это делали, чем делать предположения и жалеть позже.

Мой любимый:

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

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

Специально для новичков linux это может быть примерный пример, почему командная строка может быть полезна и упростить задачу, чем использовать инструменты графического интерфейса. Я не уверен, сколько времени потребуется для загрузки видео с youtube и преобразования его звука в mp3. Вышеуказанная строка может сделать это через несколько секунд.

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

Поэтому я бы сказал, что использование труб является клеем для сборки нескольких строительных блоков (различных инструментов UNIX). Как сказал Ульрих, sort и uniq – обычная строфа.

В зависимости от аудитории, если вы хотите выделить это использование труб, вы можете, например, начать с: «Эй, эта программа имеет ссылки на несколько интересных PDF-файлов с документами и лекциями, но некоторые из них повторяются. как-то автоматизировать это? "

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

Боюсь, это сложный пример. С другой стороны, это может помочь показать мощность труб, когда вы просто нанесете трубку и запустите оболочку сразу.

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

Другая общая строфа – это | sort | uniq | sort | uniq | sort | uniq , хотя бы потому, что uniq требует сортировки своего ввода.

Не то, чтобы вам нужно это для этого примера, но:

 $ ps aux | grep -v grep | grep conky 

… реверсирование порядка greps сохраняет окраску, но МНОГО менее эффективно. по-видимому, в больших списках, цвет не имеет значения.

Кроме того, на этой веб-странице предлагается:

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

 > Johnsyweb ответил 21/02/12 в 10:31
 > Обычный трюк:
 > ps aux |  grep '[t] erminal'
 > Это будет соответствовать строкам, содержащим терминал, который grep '[t] erminal' не делает!
 > Он также работает во многих вариантах Unix.

… но это не сработает, если вы ищете одну букву (например, процесс «X»).

Я наконец добрался, чтобы поделиться этим беспорядком из oneliner, который я сделал около полутора лет назад …

 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. Читает site.txt
  2. Запускает «хост» на каждом (оглядываясь назад, копайте + короткое, это упростило бы эту тонну)
  3. Удаляет строки, содержащие «GOOGLE» – это записи mx
  4. Возвращает строки, имеющие один из двух IP-адресов
  5. Получает код статуса http с каждого сайта в списке
  6. Удаляет сайты, которые возвращают 4xx или 5xx
  7. Удаляет «200» с сайтов, которые возвратили это
  8. Заменяет «HTTP» на «http» – чисто эстетический, никакой реальной причины.

Держу пари, это могло быть сделано намного лучше с помощью одного скрипта Python.

Это первое, что мне пришло в голову …

mysqldump – консольное приложение, которое отправляет данные, схему и необязательные процедуры и функции в стандартный вывод. Обычно он перенаправляется в файл для резервного копирования.

mysqldump <options> > mydb.dump

Это даст вам несжатый скрипт sql. Чтобы сэкономить место, вы можете сжать его с помощью bzip2.

bzip2 mydb.dump

В качестве альтернативы вы можете сделать оба за один шаг:

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

В этом примере выше, stdout из mysqldump по каналу в bzip2, который затем перенаправляет свой файл в файл.

Вот пример, который я использую в своей работе по нескольким каналам в одной команде. Это использует 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 

Трубы лучше всего работают с фильтрами и переводчиками

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

Таким образом, данные могут перетекать из одной программы в следующую буферную, и ни в коем случае все данные должны быть в памяти одновременно.

cat filename | less cat filename | less – это ужасное использование трубопроводов, поскольку вы можете просто less filename

Вот пример пипсов, которые я использую каждый день (но также может быть плохим примером): ls -la | more -c ls -la | more -c

Скотт Хоффман и ответы njsg – лучшие примеры.

Как насчет: поиск по шаблону и отображение последнего текущего шаблона?

Показывает, как использовать tail , sed и grep в контексте трубы, которые могут быть созданы шаг за шагом.

выполните это в любом каталоге, который вы хотите отсортировать, проанализируйте размер папки (затем прокрутите вниз с помощью клавиши END):

 du -m| sort -n| less 

Sortiert nach Ordnergrösse

Вот пример, который я использовал для установки переменной DISPLAY, когда xauth не был вариантом …

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

Первая команда получает необходимые данные, то есть имя хоста или IP. Вторая команда получает только данные (последнее поле). Наконец, последняя команда вырезает скобки из данных.

Командный трубопровод, который вы можете использовать везде, где вы чувствуете, что вывод первой команды может быть подан как входной сигнал в следующий.

Примеры.

  1. С текстовыми файлами вы можете передать текстовый файл в grep, чтобы найти определенные строки текста. Затем вы можете передать вывод sed или awk для изменения или печати определенной части строки.

cat example txt | grep {some_line} | awk {some_command}

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

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