Что является хорошим примером объединения команд?


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

У меня есть PID. Все, что мне нужно, это передать его kill. Для этого я буду использовать xargs.

xargs killбудет читать из ввода (в нашем случае из канала), сформировать команду, состоящую из kill <items>( <items>независимо от того, будет ли она читать из ввода), а затем выполнить созданную команду. В нашем случае это выполнится kill 1948. Миссия выполнена.

Заключительные слова

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

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


NB: Я хотел бы знать, как выполнить шаги 2 и 3 за один вызов grep. -> grep "conky -q" :)
Wolfy

3
На самом деле это плохой пример, как вы могли бы просто сделатьkill $(pgrep conky)
Патрик

5
Я знаю, что уже поздно, но вы могли бы упростить это еще дальшеpkill conky
Струге

2
"" "Примечание: я хотел бы знать, как выполнить шаги 2 и 3 за один вызов grep." "" Вместо "aux" используйте "-o pid, comm" - это также более переносимо, так как это POSIX -совместимый. Таким образом, процесс grep будет отображаться как «grep» вместо «grep conky», так что он не будет соответствовать самому себе.
Random832

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 это может быть практическим примером того, почему командная строка может быть полезна и упрощает работу, чем использование инструментов с графическим интерфейсом. Я не уверен, сколько времени потребуется, чтобы скачать видео с YouTube и преобразовать его звук в mp3. Приведенная выше строка может сделать это за несколько секунд.


3
У youtube-dl есть возможность сохранять только аудио. Моя обычная команда это, где адреса приходят на стандартный ввод: youtube-dl --extract-audio --audio-format mp3 -a -. Все еще классный пример, но есть более простые способы сделать это. (Он вызывает ffmpeg внутри.)
Разбойник

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 .
Тереза ​​и младший

2

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

Еще одна распространенная строфа - | sort | uniqхотя бы потому, что uniqтребует сортировки входных данных.


Большинство людей предпочитают, ... | sort -uесли доступно!

2

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

$ ps aux | grep -v grep | grep conky

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

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

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

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


Э-э ... Я не уверен, что это был бы самый чистый и простой пример для объяснения трубопровода новичку;)
Эратиэль

2
У меня вопрос, какова его цель?
ADTC

У меня был файл, полный доменов, и мне нужно было проверить, были ли они на одном из двух моих серверов (которые я «унаследовал», к сожалению). Это читает файл, выполняет «хост» и очищает этот вывод, затем просто делает запрос, чтобы увидеть, возвращает ли он ошибку 4xx или 5xx. Если бы он это сделал, то он бы отбросил домен; если нет, он выводит их, и я помещаю его в другой файл.
Таннер

1

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

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

mysqldump <options> > mydb.dump

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

bzip2 mydb.dump

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

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

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


1
Добавьте перевернутую операцию тоже: bzcat mydb.dump.bz2 | mysql <options>.
manatwork

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

Скотт Хоффман и NJSG ответы являются лучшими примерами.



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. С текстовыми файлами вы можете передать текстовый файл в grep, чтобы найти определенные строки текста. Затем вы можете передать вывод в sed или awk, чтобы изменить или напечатать определенную часть строки.

пример кошки TXT | grep {some_line} | awk {some_command}

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.