Как передать вывод tail-f в сценарий оболочки

#bash #tail

Вопрос:

Я хочу отслеживать журналы сервера с помощью telegram bot api с помощью этого скрипта:

 #!/bin/bash
CHATID="id"
KEY="key"
TIME="10"
URL="https://api.telegram.org/bot$KEY/sendMessage"
TEXT=$(tee)

curl -s --max-time $TIME -d "chat_id=$CHATIDamp;disable_web_page_preview=1amp;text=$TEXT" $URL >/dev/null
 

Затем передайте выходные данные журналов в скрипт с помощью:

 tail -f /var/log/my.log | ./telegram_log.sh
 

Но он не отправляет выходные данные.

Комментарии:

1. чего вы хотите достичь? отправляете сообщение в каждой новой строке журнала?

2. @MarcoLucidi да, именно это

3. затем вы должны обработать каждую входящую строку. на данный момент я думаю, что ваш сценарий застрял в TEXT=$(tee) ожидании stdin завершения/закрытия, но этого никогда не произойдет, потому tail -f что он остается открытым.

4. @MarcoLucidi должен ли я тогда использовать цикл? Можете ли вы привести пример?

5. да, цикл, я пишу пример

Ответ №1:

ваш сценарий остается застрявшим в строке

 TEXT=$(tee)
 

потому tee что он ждет stdin , когда его закроют, но этого никогда не произойдет, потому tail -f что он остается открытым, чтобы «следовать» за файлом.

чтобы отправить сообщение в каждой новой строке журнала, вы должны обрабатывать каждую входящую строку, а не ждать всю stdin . простой while read должен это сделать, например:

 $ more bot.sh
#!/bin/sh

while IFS= read -r line; do
        echo send new line as msg: "$line"
        # TODO here goes curl etc...
done
$ touch log
$ tail -f log | ./bot.sh
send new line as msg: hello
send new line as msg: world
send new line as msg: goodbye
 

и на другом терминале я сделал:

 $ echo hello >> log
$ echo world >> log
$ echo goodbye >> log
$