2013-08-07 3 views
10

Я должен скрипты:Linux скрипт с Netcat перестает работать после й часов

#!/bin/bash 

netcat -lk -p 12345 | while read line 
do 
    match=$(echo $line | grep -c 'Keep-Alive') 
    if [ $match -eq 1 ]; then 
     [start a command] 
    fi 
done 

и

#!/bin/bash 

netcat -lk -p 12346 | while read line 
do 
    match=$(echo $line | grep -c 'Keep-Alive') 
    if [ $match -eq 1 ]; then 
     [start a command] 
    fi 
done 

Я поставил два сценарий в /etc/init.d»/'

Когда я перезагружаю свою машину Linux (RasbPi), оба скрипта работают нормально.

Я пробовал их как 20 раз, и они продолжают работать нормально.

Но примерно через 12 часов вся система перестает работать. Я включил некоторый loggin, но кажется, что скрипты больше не реагируют. Но когда я;

ps aux 

Я могу видеть, что сценарии все еще работают:

root  1686 0.0 0.2 2740 1184 ?  S Aug12 0:00 /bin/bash /etc/init.d/script1.sh start 
root  1689 0.0 0.1 2268 512 ?  S Aug12 0:00 netcat -lk 12345 
root  1690 0.0 0.1 2744 784 ?  S Aug12 0:00 /bin/bash /etc/init.d/script1.sh start 
root  1691 0.0 0.2 2740 1184 ?  S Aug12 0:00 /bin/bash /etc/init.d/script2.sh start 
root  1694 0.0 0.1 2268 512 ?  S Aug12 0:00 netcat -lk 12346 
root  1695 0.0 0.1 2744 784 ?  S Aug12 0:00 /bin/bash /etc/init.d/script2.sh start 

После перезагрузки они начинают работать снова ... Но то грех, перезагружая машину Linux периодически ...

Я вставил некоторый loggin, вот результат;

Listening on [0.0.0.0] (family 0, port 12345) 
[2013-08-14 11:55:00] Starting loop. 
[2013-08-14 11:55:00] Starting netcat. 
netcat: Address already in use 
[2013-08-14 11:55:00] Netcat has stopped or crashed. 
[2013-08-14 11:49:52] Starting loop. 
[2013-08-14 11:49:52] Starting netcat. 
Listening on [0.0.0.0] (family 0, port 12345) 
Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6333) 
Connection closed, listening again. 
Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6334) 
[2013-08-14 12:40:02] Starting loop. 
[2013-08-14 12:40:02] Starting netcat. 
netcat: Address already in use 
[2013-08-14 12:40:02] Netcat has stopped or crashed. 
[2013-08-14 12:17:16] Starting loop. 
[2013-08-14 12:17:16] Starting netcat. 
Listening on [0.0.0.0] (family 0, port 12345) 
Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6387) 
Connection closed, listening again. 
Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6388) 
[2013-08-14 13:10:08] Starting loop. 
[2013-08-14 13:10:08] Starting netcat. 
netcat: Address already in use 
[2013-08-14 13:10:08] Netcat has stopped or crashed. 
[2013-08-14 12:17:16] Starting loop. 
[2013-08-14 12:17:16] Starting netcat. 
Listening on [0.0.0.0] (family 0, port 12345) 
Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6167) 
Connection closed, listening again. 
Connection from [16.8.94.19] port 12345 [tcp/*] accepted (family 2, sport 6168) 

Благодаря

+0

не вижу проблемы, но я мало знаю о netcat. НО вы можете уменьшить количество процессов, созданных вами, заменив 'match = ... fi' на' do; если grep -q «Keep-Alive»; затем запустите cmd; fi'. Удачи. – shellter

+0

Я только что пробовал это, но это останавливает все, от работы ... – Lectere

+3

+1 «Но это грех».Я подозреваю, особенно в свете флага «-k» keep-alive на netcat, что IP-уровень отскакивает через много часов либо через истечение срока аренды DHCP, либо «самовосстановление» (т.е. перезагрузка ежедневно, потому что это проще, чем исправление ошибок) » функции вашего etherswitch. «/ Var/log/syslog» дает вам подсказку? – msw

ответ

1

вы не можете использовать опцию -p в случае, если вы будете ждать входящего запроса на подключение. (см. Справочную страницу nc). Имя хоста и порт - это два последних аргумента командной строки.

Может быть, он подключается к собственному порту, и через несколько часов отсутствует какой-то ресурс?

+0

Хорошая мысль, но я также заметил, что при чтении страниц man netcat. Я удалил параметр -p. Но это не помогает. Что вы имеете в виду со своим вторым замечанием? – Lectere

+0

Это только подозрительное подозрение. Я так и не использовал netcat. Опция -p - это опция, которая используется для исходящих запросов на соединение. Смутное подозрение: netcat может попытаться инициировать некоторый запрос из-за этого параметра. Но вы говорите, что это не разница. – tue

3

Вы упомянули «примерно через 12 часов вся система перестает работать» - Вероятно, скрипты выполняются независимо от того, что у вас есть в [start a command] и раздувает память. Вы уверены, что [start a command] не очень часто вызывает много процессов и освобождает память?

+0

Хорошая точка, чтобы это исключить, мне придется удалить команду и эхо в файл журнала. Чтобы увидеть, остается ли работа без моего стартового скрипта. – Lectere

+0

Я добавил loggin, и команда не испортила его. – Lectere

+0

Итак, вы говорите, что вы удалили часть [start a command], и ваш скрипт не ответил после 12 часов? –

3

У меня часто возникало странное поведение с nc или netcat. Вы должны посмотреть на ncat, это почти тот же инструмент, но он ведет себя одинаково на всех платформах (nc и netcat ведут себя по-разному в зависимости от дистрибутива, Linux, BSD, Mac).

+0

У меня там какое-то странное поведение. Tnx для замены на замену. –

5

О петле это может выглядеть так.

#!/bin/bash 

for ((;;)) 
do 
    netcat -lk -p 12345 | while read line 
    do 
     match=$(echo "$line" | grep -c 'Keep-Alive') 
     if [ "$match" -eq 1 ]; then 
      [start a command] 
     fi 
    done 
    sleep 4s 
done 

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

И вы могли бы попытаться захватить ошибки и добавить протоколирование с этим форматом:

#!/bin/bash 

{ 
    echo "[$(date "+%F %T")] Starting loop." 

    for ((;;)) 
    do 
     echo "[$(date "+%F %T")] Starting netcat." 

     netcat -lk -p 12345 | while read line 
     do 
      match=$(echo "$line" | grep -c 'Keep-Alive') 
      if [ "$match" -eq 1 ]; then 
       [start a command] 
      fi 
     done 

     echo "[$(date "+%F %T")] Netcat has stopped or crashed." 

     sleep 4s 
    done 
} >> "/var/log/something.log" 2>&1 

Ваша команда чтения также может быть лучше в этом формате, так как он будет читать строки немодифицированных:

... | while IFS= read -r line 

Некоторые может также предложить использование замещения процесса, но я не рекомендую его на этот раз, поскольку с помощью метода | while ... цикл while может работать на подоболочке и поддерживать внешний цикл for в безопасности n в случае сбоя. Кроме того, на самом деле нет переменной из цикла while, которая понадобилась бы за ее пределами.

Я на самом деле имея идею теперь, что этот вопрос действительно может быть связан с входом и как блок while read line; do ...; done обрабатывает его и не NetCat себя. Ваши переменные, которые не правильно цитируются вокруг «", могут быть одним из них: или, вероятно, может быть фактической причиной, почему ваш netcat рушится.

+0

Хороший материал !, добавил некоторые регистрации и дополнительный цикл, если netcat останавливается ... Я собираюсь попробовать это прямо сейчас, если это сработает, я дам вам очки! Благодаря! – Lectere

+0

Если вы не используете его как root, и если у вашего пользователя нет права на запись в каталоге записи, возможно, вы можете просто использовать домашний каталог: '} >> ~/something.log 2> & 1' или создать файл с правами на запись для пользователя как root: 'touch /var/log/something.log; chown youruser: yourusersgroup /var/log/something.log; chmod 644 /var/log/something.log # или 600 по вашему желанию' – konsolebox

+0

Я работаю как root, поэтому все в порядке. Я также добавил строку кода журнала, когда событие является triggerd. На самом деле думаю, что мы здесь в правильном направлении. Теперь мы можем определить, в какой фазе он сбой. Я также выяснил, что во время загрузки скрипт выдает ошибку 3 раза и перезапускается 3 раза. Спасибо, что помогли мне с синтаксисом, если бы это была powershell, я бы не проблема для меня, но я не так хорош с Linux ... – Lectere

5

Если ни одна из ваших команд, включая netcat, не считывает входные данные из stdin, вы можете полностью запустить ее независимо от терминала. Иногда фоновый процесс, который все еще зависит от терминалов, приостанавливает (S), когда они пытаются прочитать ввод из него на фоне. Фактически, поскольку вы используете демона, вы должны убедиться, что ни одна из ваших команд не считывает ввод с него (терминал).

#!/bin/bash 

set +o monitor # Make sure job control is disabled. 

(
    : # Make sure the shell runs a subshell. 
    exec netcat -lk -p 12345 | while read line ## Use exec to overwrite the subshell. 
    do 
     match=$(echo $line | grep -c 'Keep-Alive') 
     if [ $match -eq 1 ]; then 
      [start a command] 
     fi 
    done 
) <&- >&- 2>&- </dev/null &>/dev/null & 

TASKPID=$! 
sleep 1s ## Let the task initialize a bit before we disown it. 
disown "$TASKPID" 

И я думаю, что мы могли бы попробовать протоколирования вещь снова:

set +o monitor 

(
    echo "[$(date "+%F %T")] Starting loop with PID $BASHPID." 

    for ((;;)) 
    do 
     echo "[$(date "+%F %T")] Starting netcat." 

     netcat -vv -lk -p 12345 | while read line 
     do 
      match=$(echo "$line" | grep -c 'Keep-Alive') 
      if [ "$match" -eq 1 ]; then 
       [start a command] 
      fi 
     done 

     echo "[$(date "+%F %T")] Netcat has stopped or crashed." 

     sleep 4s 
    done 
) <&- >&- 2>&- </dev/null >> "/var/log/something.log" 2>&1 & 

TASKPID=$! 
sleep 1s 
disown "$TASKPID" 
+0

Так что я должен попробовать второй ?, с loggin, но должен ли он также включать «exec» для запуска в подоболочке? – Lectere

+0

Честно говоря, я не уверен, что ведение журналов снова приведет к остановке сценариев, поэтому, возможно, я могу предложить вам попробовать один с протоколированием, а затем попробовать один без него. О exec это не проблема, не беспокойтесь, поскольку() уже будет отделен от родительской оболочки как целого, и, надеюсь, и от атрибутов терминала. Если он все еще не работает, я бы предложил использовать другой netcat, например, оригинальный netcat или gnu-netcat. – konsolebox

+0

Okey, я попробую второй, с логгином. Результаты завтра :) – Lectere

2

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

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

Мое решение для вас, чтобы трубы на выходе из Netcat в SED, то трубы, что (значительно уменьшенный) линии к прочитанному ... встроенной команды

#!/bin/bash 

{ 
    echo "[$(date "+%F %T")] Starting loop." 

    for ((;;)) 
    do 
     echo "[$(date "+%F %T")] Starting netcat." 

     netcat -lk -p 12345 | sed 's/.*Keep-Alive.*/Keep-Alive/g' | \ 
     \ 
     while read line 
     do 
      match=$(echo "$line" | grep -c 'Keep-Alive') 
      if [ "$match" -eq 1 ]; then 
       [start a command] 
      fi 
     done 

     echo "[$(date "+%F %T")] Netcat has stopped or crashed." 

     sleep 4s 
    done 
} >> "/var/log/something.log" 2>&1 

Кроме того, вы должны рассмотреть некоторые из другие программы запуска в /etc/init.d, чтобы убедиться, что они совместимы с любой версией rc, используемой системой, однако было бы гораздо проще вызвать ваш script2.sh из копии какого-либо простого файла в init.d , Поскольку скрипт2 является скриптом запуска, но не соответствует используемому пакету init.

Это звучит более сложно, что я имею в виду ... Позвольте мне объяснить лучше:

/etc/init.d/syslogd  ## a standard init script that calls syslogd 
/etc/init.d/start-monitor ## a copy of a standard init script that calls script2.sh 

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

+0

У ksh есть 'read -r' (raw), и, возможно, есть и' -b'. Не уверен насчет 'bash'. Всем удачи. – shellter