Я пытаюсь tail
записать файл журнала на несколько удаленных компьютеров и переслать вывод на мою локальную рабочую станцию. Я хочу, чтобы соединения закрывались при нажатии Ctrl- C.
На данный момент у меня есть следующая функция, которая почти работает как задумано.
function dogfight_tail() {
logfile=/var/log/server.log
pids=""
for box in 02 03; do
ssh server-$box tail -f $logfile | grep $1 &
pids="$pids $!"
done
trap 'kill -9 $pids' SIGINT
trap wait
}
Соединения закрываются, и я получаю вывод от tail
. НО, происходит какая-то буферизация, потому что выходные данные идут партиями.
И вот самое интересное…
Я могу видеть такое же поведение буферизации при выполнении следующего и добавляю «test» к файлу /var/log/server.log
на удаленных машинах 4-5 раз…
ssh server-01 "tail -f /var/log/server.log | grep test"
... и нашел два способа его отключения ...
Добавьте флаг -t в ssh.
ssh -t server-01 "tail -f /var/log/server.log | grep test"
Удалить цитату из удаленной команды.
ssh server-01 tail -f /var/log/server.log | grep test
Однако ни один из этих подходов не работает для функции, которая выполняется на нескольких машинах, упомянутых выше.
Я пробовал dsh, которые имеют такое же поведение буферизации при выполнении.
dsh -m server-01,server-02 -c "tail -f /var/log/server.log | grep test"
То же самое и здесь, если я уберу цитату, буферизация исчезнет, и все будет нормально.
dsh -m server-01,server-02 -c tail -f /var/log/server.log | grep test
Также попробовал, parallel-ssh
который работает точно так же, как dsh
. Может кто-нибудь объяснить, что здесь происходит?
Как мне решить эту проблему? Было бы идеальным, чтобы пойти с прямой, ssh
если это возможно.
PS Я не хочу использовать multitail
или подобное, так как я хочу иметь возможность выполнять произвольные команды.
dbitail
и скачать его отсюда .Ответы:
То, что вы видите, является эффектом стандартного буфера stdout,
grep
предоставленного Glibc. Лучшее решение - отключить его с помощью--line-buffered
(GNU grep, я не уверен, какие другие реализации могут его поддерживать или что-то подобное).Что касается того, почему это происходит только в некоторых случаях:
запускает всю команду в кавычках на сервере - таким образом
grep
ждет заполнения своего буфера.работает
grep
на вашем локальном компьютере на выходе,tail
отправленном через канал ssh.Ключевой частью здесь является то, что он
grep
регулирует свое поведение в зависимости от того,stdin
является ли он терминалом или нет. Когда вы запускаетеssh -t
, удаленная команда работает с управляющим терминалом, и, таким образом, удаленныйgrep
ведет себя как ваш локальный.источник
ssh tail | grep
выходы на локальный терминал, небуферизованные.ssh -t "tail|grep"
выводит в pty, небуферизованный.ssh "tail|grep"
вывод на канал (доsshd
), буферизированный (если не--line-buffered
).Проверь это:
multitail
MultiTail позволяет отслеживать журналы и вывод команд в нескольких окнах в терминале, раскрашивать, фильтровать и объединять.
Для привязки журналов на нескольких серверах используйте:
источник
multitail <(ssh …) <(ssh …)
что позволяет получить желаемый результат, даже если они не думали, что на этот вопрос можно было ответить.Вы можете оформить заказ в личном журнале.
Я создал инструмент Java, способный читать локальные и удаленные файлы журналов, используя SSH. Это довольно просто в использовании.
Еще несколько объяснений: https://github.com/pschweitz/insidelog/wiki
Просто загрузите версию, соответствующую вашей операционной системе, с собственным исполняемым файлом jar release в вашей среде выполнения Java (требуется java 8_40 или выше):
https://github.com/pschweitz/insidelog/releases
Вы можете найти полную документацию (в том числе и на странице Github)
источник