LinuxForum.Fans
Тема

Объединение команд в shell

Автор: Cruiser78 12 сообщений 4611 просмотров
#122921

Что то я туплю сегодня.

Постановка задачи: сервер с двумя сетевыми интерфейсами (eth0 и eth1). Надо слушать оба эти интерфейса и наравлять услышанное в программу анализатор. Собственно это один из антиспамовских модулей на почтовом сервере - интегрирую p0f и amavis-new.
В руководстве сказано - делай "p0f -i eth0 bla-bla-bla | p0f-analyzer.pl 2345 &" и радуйся.
А интерфейса - два. Поэтому радости не испытываю. Анализатор-то должен быть один. Как сконструировать команду, чтобы p0f сел на 2 интерфейса - не понимаю. Конструкция вида "(p0f -i eth0 & ; p0f -i eth1) | p0f-analyzer.pl 2345 &" не проходит. Шелл ругается на ошибку вблизи ";"... Причем влияет на это дело "&" перед ";".
Есть выход - замутить более сложную маршрутизацию и подвести трафик с одного интерфейса, но здесь много проблем...
А вот как команду написать - не соображу. Не соображу, как первую команду запустить демоном, а весь её выходной поток, вместе с выходом второй команды направить в анализатор.
=================================
Спасибо, тема закрыта. Действительно, затупил и про FIFO забыл начисто.

#122949
Cruiser78 написал:
Собственно это один из антиспамовских модулей на почтовом сервере - интегрирую p0f и amavis-new.
В руководстве сказано - делай "p0f -i eth0 bla-bla-bla | p0f-analyzer.pl 2345 &" и радуйся.

в данном случае команда p0f генерирует некий поток информации, который через пайп (читать про pipe) отправляется на вход перлового скрипта p0f-analyzer.pl
при этом команда завершается на ампресанд (&), потому она выполняется в фоновом режиме.

Cruiser78 написал:
А вот как команду написать - не соображу.

что за команды-то? где ссылка на руководство к ним? телепаты в отпуске.

#122977
drBatty написал:
что за команды-то? где ссылка на руководство к ним? телепаты в отпуске.

Ну, все команды были приведены в топикстартовом спиче. Чтобы из прочитать - телепатом быть не надо.
Проблема - объединить стандартный вывод некольких процессов (неважно каких) и загнать это объединение на стандартный вход третьего процесса, анализатора. Решается через FIFO на раз.

#123017
Cruiser78 написал:
Чтобы из прочитать - телепатом быть не надо.

[console]$ p0f
bash: p0f: command not found
[/console]

Cruiser78 написал:
Проблема - объединить стандартный вывод некольких процессов (неважно каких) и загнать это объединение на стандартный вход третьего процесса, анализатора. Решается через FIFO на раз.

это не проблема.
[console]$ ( ls; ls ) >/dev/null[/console]

#123018

для гурманов:

[console]$ ( ls; ls ) | ls[/console]

#123024
Cruiser78 написал:
Спасибо, тема закрыта. Действительно, затупил и про FIFO забыл начисто.

вот уж затупил так затупил - FIFO тут не при чём!!!
сами тупите, и других путаете :[

лично вам, Cruiser78, читать до полного просветления:

Показать
FIFO(7) Linux Programmer's Manual FIFO(7)

NAME
fifo - first-in first-out special file, named pipe

DESCRIPTION
A FIFO special file (a named pipe) is similar to a pipe, except that it is accessed as part of the file
system. It can be opened by multiple processes for reading or writing. When processes are exchanging data
via the FIFO, the kernel passes all data internally without writing it to the file system. Thus, the FIFO
special file has no contents on the file system; the file system entry merely serves as a reference point
so that processes can access the pipe using a name in the file system.

The kernel maintains exactly one pipe object for each FIFO special file that is opened by at least one
process. The FIFO must be opened on both ends (reading and writing) before data can be passed. Normally,
opening the FIFO blocks until the other end is opened also.

A process can open a FIFO in non-blocking mode. In this case, opening for read only will succeed even if
no-one has opened on the write side yet, opening for write only will fail with ENXIO (no such device or
address) unless the other end has already been opened.

Under Linux, opening a FIFO for read and write will succeed both in blocking and non-blocking mode. POSIX
leaves this behavior undefined. This can be used to open a FIFO for writing while there are no readers
available. A process that uses both ends of the connection in order to communicate with itself should be
very careful to avoid deadlocks.

NOTES
When a process tries to write to a FIFO that is not opened for read on the other side, the process is sent
a SIGPIPE signal.

FIFO special files can be created by mkfifo(3), and are indicated by ls -l with the file type 'p'.

SEE ALSO
mkfifo(1), open(2), pipe(2), sigaction(2), signal(2), socketpair(2), mkfifo(3), pipe(7)

COLOPHON
This page is part of release 3.15 of the Linux man-pages project. A description of the project, and infor-
mation about reporting bugs, can be found at http://www.kernel.org/doc/man-pages/.

Linux 2008-12-03 FIFO(7)

остальным замечу, что невозможно объединить объединённое - поток /dev/stdout уже и так один. Просто здесь нужно перенаправить поток от двух команд в другое место. Это решается многими способами, самый простой из которых - запустить команды в отдельном дочернем шелле, и перенаправить вывод не от команд, а от всего этого шелла. Я просто записал две команды в (скобках).

#123250
drBatty написал:

это не проблема.
[console]$ ( ls; ls ) >/dev/null[/console]

Как раз проблема. А именно - с командами типа ls и иже с ними проблемы нет. Эти команды исполяемы за конечное время. И вторая команда начинается по завершении первой. Здесь нет вообще проблем.
А вот предлагаю таким же способом анализировать одновременно два сетевых интерфейса программкой tcpdump. Повесь на каждый по бесконечному tcpdump'у. А стандартный вывод этого направь в какой либо grep для выявления нужной сигнатуры. Вперед. До полного просветления. Если это сделаешь без FIFO, а так, как здесь предлагаешь, скобочками да ";" - расскажи, как сумел.

#123787
Cruiser78 написал:
[quote=drBatty]
это не проблема.
[console]$ ( ls; ls ) >/dev/null[/console]

Как раз проблема. А именно - с командами типа ls и иже с ними проблемы нет. Эти команды исполяемы за конечное время. И вторая команда начинается по завершении первой. Здесь нет вообще проблем.
А вот предлагаю таким же способом анализировать одновременно два сетевых интерфейса программкой tcpdump. Повесь на каждый по бесконечному tcpdump'у. А стандартный вывод этого направь в какой либо grep для выявления нужной сигнатуры. Вперед. До полного просветления. Если это сделаешь без FIFO, а так, как здесь предлагаешь, скобочками да ";" - расскажи, как сумел.[/quote]

[console]$ ( ( tail -f .bashrc & ) ; ( tail -f .bashrc & ) ) | grep "XYZ" &
[6] 11239
ksu@ksu:~$ echo "XYZ" >> .bashrc
ksu@ksu:~$ XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
XYZ
[/console]
так много из-за экспериментов, я, честно говоря, смутно помню этот хак.
Кстати, вежливые вы мои, где ваше решение с FIFO?

PS: хотя да, фигня получается. лень думать и вспоминать, как именно я это делал. но проблемы тут особой действительно нет, фокус в том, что можно запустить в субшеле команду в интерактивном режиме. Другое дело, что необходимость в этом возникает очень редко (лишь в очень сложных скриптах, когда начинаешь задумываться, "может ну его, написать на С и не заморачиваться?").

#123812
drBatty написал:
[console]$ ( ( tail -f .bashrc & ) ; ( tail -f .bashrc & ) ) | grep "XYZ" &
[/console]

Я до вторых скобок не додумался. А херни не получается - ты читаешь одно и тоже два раза. Если читать из разных файлов - всё намано.

drBatty написал:

так много из-за экспериментов, я, честно говоря, смутно помню этот хак.
Кстати, вежливые вы мои, где ваше решение с FIFO?

Кусочек инициализирующего скрипта для съема информации с двух интерфейсов и заведения этой информации в анализатор приведен ниже

text
fifo=/dev/shm/p0f-fifo 
/usr/bin/mkfifo $fifo 
/usr/sbin/p0f -i eth0 -l 'tcp dst port 25' >$fifo 2>&1 & 
/usr/sbin/p0f -i eth1 -l 'tcp dst port 25' >$fifo 2>&1 & 
cat < $fifo | /usr/local/sbin/p0f-analyzer.pl 2345 &  

Здесь пара процессов пишут в fifo, которое раположено в ram, а один процесс постоянно её (точнее - по запросу от службы антиспамовской защиты) оттуда вычитывает. Если бы был один интерфейс, то решение тривиальное, как в инструкции сказано: p0f | p0f-alalizer.pl & . А вот на два интерфейса - я затормозил.

#123843
Cruiser78 написал:
Я до вторых скобок не додумался.

ну я думал ты знаешь про ( command & ). Просто внутри скриптов & не работает, и приходится запускать из баша другой баш, а у же в этом втором баше & срабатывает как надо.

(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable
assignments and builtin commands that affect the shell's environment do not remain in effect after
the command completes. The return status is the exit status of list.

Вот про вторые скобки я и писал в первый раз в конструкции ( ls ; ls ).

Cruiser78 написал:
А херни не получается - ты читаешь одно и тоже два раза. Если читать из разных файлов - всё намано.

а, ну да. ты прав.

Cruiser78 написал:
Кусочек инициализирующего скрипта для съема информации с двух интерфейсов и заведения этой информации в анализатор приведен ниже

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

#124094
drBatty написал:
[quote=Cruiser78]Я до вторых скобок не додумался.

ну я думал ты знаешь про ( command & ). Просто внутри скриптов & не работает, и приходится запускать из баша другой баш, а у же в этом втором баше & срабатывает как надо.
[/quote]

Я изучал юникс (скотинку) лет 15 назад на краткосрочных 2х-недельных курсах. Но, с тех пор моя работа была хоть и рядом с ним, но непосредственно к "станку" мне подходить нужды не было. Так что, часть знаний из башки с годами выветрилась.

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

А чем STDOUT отличается от любого файла? Только тем, что он открывается процессу по дефолту всегда, а иные файлы надо открывать явно?

Войдите или зарегистрируйтесь, чтобы ответить.