Скрипт уровня сигнала. Добавить цикл из 5 попыток.

Автор bboymig, 08 сентября 2016, 10:50:33

« назад - далее »

0 Пользователи и 2 гостей просматривают эту тему.

bboymig

Есть небольшой скрипт, который выводит уровень сигнала. Если от модема не поступила информация, то выводит 0.
Помогите сделать условие. Если вышел 0, то запустить скрипт по новой. Если после 5 попытки вышел 0, то отправляем 0. Если вышло значение в любой из попытки, то отправляем значение.
Цитироватьecho -e "AT+CSQ\r\n" > /dev/ttyUSB0
sleep 1
gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' /dev/ttyUSB0 || echo 0
Прошу помощи, так как не знаю синтаксиса вообще.

endru

может немного погуглить? обленились все в последнее время...
тебе поможет обычный цикл for, результат выполенения команды передаешь в переменную, например:
temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' /dev/ttyUSB0 || echo 0`
после значение переменной можешь проверить условием, и если оно отлично от нуля - выходишь с выводом echo $temp

bboymig

#2
Цитировать
#!/bin/bash
i=5
if [i -ne 0] then i-1
echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
sleep 1
temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' /dev/ttyUSB0 || echo 0`
if [$temp -ne 0] then echo $temp
else echo $temp
fi

endru

bboymig, а где сам цикл то?
for in in 1 2 3 4 5 #5 циклов
do
echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
sleep 1
temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' /dev/ttyUSB0 || echo 0`
if [ "$temp" -ne "0" ]
then
echo $temp
break #прерываем цикл
fi
done

bboymig

Спасибо. Сам давно программированием занимался. Все уже забыл. Ассемблер и Паскаль.

bboymig

#5
Бывает при выполнении скрипта строчка   temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' /dev/ttyUSB0 || echo 0` зависает напрочь.
Скрипт изменил:
Цитировать#!/bin/bash
temp="0";
i="0";
for i in {1..6}; do
  if [ $i -eq 6 ]; then
                   echo $temp;
                   break
                   fi
  if [ $i -lt 6 ]; then
  echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
  cat /dev/ttyUSB0 > gsm.txt & sleep 1; pkill %cat;
  temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' gsm.txt || echo 0`
   if [ "$temp" -ne "0" ]
   then
   clear;
   echo $temp
   break #прерываем цикл
   fi
  fi
done
Проблема заключается в следующем. cat сразу же передает информацию в файл gsm.txt. Нельзя сделать так, чтобы cat в течении 1-2 секунды считывал всю информацию и полученную информацию отправлял в файл?

Пробовал сделать так:
Цитировать
#!/bin/bash
temp="0";
i="0";
for i in {1..6}; do
  if [ $i -eq 6 ]; then
                   echo $temp;
                   break
                   fi
  if [ $i -lt 6 ]; then
  echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
  cat /dev/ttyUSB0 & sleep 2 & /dev/pts/0 > gsm.txt & pkill %cat;
  temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' gsm.txt || echo 0`
   if [ "$temp" -ne "0" ]
   then
   clear;
   echo $temp
   break #прерываем цикл
   fi
  fi
done
Выдает ошибку об отказе доступа:
Цитироватьline 11: /dev/pts/0: Отказано в доступе
chmod 777 /dev/pts/0
chown root:zabbix /dev/pts/0

Самое обидное, что крайнее решение задачи скорее всего не подойдет по причине вывода информации. И что делать я не знаю.

vic5710

#6
Цитата: bboymig от 08 сентября 2016, 13:17:34Проблема заключается в следующем. cat сразу же передает информацию в файл gsm.txt. Нельзя сделать так, чтобы cat в течении 1-2 секунды считывал всю информацию и полученную информацию отправлял в файл?

tmp=$(mktemp)
for i in 1 2 3
do
sleep 1
cat /dev/ttyUSB0 >>$tmp
done

можно так
зачем тут pkill я не понял

cat /dev/ttyUSB0 & sleep 2 & /dev/pts/0 > gsm.txt & pkill %cat;

что эта строка делает?

Cообщение объединено 11 сентября 2016, 00:17:43

тут похожий случай
cat у тебя будет висеть, пока не получит EOF, его тут применять сомнительно, нужно неблокирующее чтение
или запусти в фоне в начале

tmp=$mktemp) # create empty file
while true
do
sleep 1# 1 sec delay
cat /dev/ttyUSB0 >> $tmp #дописываем данные в tmpfile
done & #запускаем в бесконечном цикле

если нужно очистить данные - echo > $tmp
погугли "linux open file non-block read", я когда-то на С делал, но не помню уже, ЕМНИП через <termios.h>

Cообщение объединено 11 сентября 2016, 02:20:02

нашел в закромах

//read_tty.c
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>

#define readsize 512
#define devname "/dev/ttyUSB0"
#define baudrate B115200

int main() {
    struct termios ts_old,ts_new;
    memset(&ts_old,0,sizeof(ts_old));
    memset(&ts_new,0,sizeof(ts_new));
    ts_new.c_cflag |= (baudrate | CS8 | CREAD | CLOCAL | HUPCL);
    ts_new.c_cflag &= ~(CRTSCTS | PARENB | PARODD);
    ts_new.c_iflag &= ~(IXON | IXOFF | IGNCR | ICRNL | ISTRIP | INLCR);
    ts_new.c_lflag &= ~(ICANON | ECHO);
    ts_new.c_oflag = 0;
    ts_new.c_cc[VMIN] = 0;
    ts_new.c_cc[VTIME] = 0;
    int count,fd;
    char buffer[readsize];
    fd = open(devname, O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
fprintf(stderr,"error open file\n");
return -1;
    }
    tcgetattr(fd,&ts_old);
    tcsetattr(fd,TCSANOW,&ts_new);
    count = read(fd,buffer,readsize);
    tcsetattr(fd,TCSANOW,&ts_old);
    close(fd);
    if (count < 0) {
fprintf(stderr,"error read file\n");
return -1;
    }
    write(1,buffer,count);
    return 0;
}


bboymig

Цитировать#!/bin/bash
echo > gsm.txt
while true
do
sleep 0.5
cat /dev/ttyUSB0 >> gsm.txt
done &
temp="0";
i="0";
for i in {1..3}; do
  if [ $i -eq 3 ]; then
                   echo $temp;
                   break
                   fi
  if [ $i -lt 3 ]; then
   echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
   temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' gsm.txt || echo 0`
   if [ "$temp" -ne "0" ]
   then
   clear;
   echo $temp
   break #прерываем цикл
   fi
  fi
done
Спасибо. В данном случае скрипт отрабатывает очень быстро. Я на работе еще на проблемном модеме проверю, очень надеюсь, что данный вопрос закроется.  :)

vic5710

Цитата: bboymig от 11 сентября 2016, 09:12:35Я на работе еще на проблемном модеме проверю, очень надеюсь, что данный вопрос закроется. 
:o
Открыть содержимое (спойлер)

я буду удивлен если будет так.
ты сам-то понял ,что написал?
[свернуть]
учите матчасть

endru

зачем вообще использовать cat для потока? есть же tail -f

vic5710

Цитата: endru от 12 сентября 2016, 05:37:52
зачем вообще использовать cat для потока? есть же tail -f
в смысле вместо cat /dev/* ? не знаю, не применял

bboymig

#11
Добрый день.
Алгоритм работает не так как надо. Это логично.
Цитироватьecho > gsm.txt
while true
do
sleep 0.5
cat /dev/ttyUSB0 >> gsm.txt
done &
Данный цикл не прекращает своей работы после выполнения скрипта. Можно было бы его закончить, после выполнения скрипта.

Пробовал сделать так:
Цитировать#!/bin/bash
echo > gsm.txt
temp="0";
i="0";
for i in {1..5}; do
  if [ $i -eq 5 ]; then
                   echo $temp;
                   break
                   fi
  if [ $i -lt 5 ]; then
   echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
   tail -f /dev/ttyUSB0 | tee gsm.txt &
   temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' gsm.txt || echo 0`
   if [ "$temp" -ne "0" ]
   then
   echo $temp
   break #прерываем цикл
   fi
  fi
done

tail -f выводит информацию, что не требуется. Все что выводится передается агенту zabbix.

Задача всего ничего. 100% гарантией считать полученную информацию с модема.

vic5710


bboymig

Цитировать#!/bin/bash
echo > gsm.txt
temp="0";
i="0";
for i in {1..5}; do
  if [ $i -eq 5 ]; then
                   echo $temp;
                   break
                   fi
  if [ $i -lt 5 ]; then
   echo -e "AT+CSQ\r\n" > /dev/ttyUSB0
   tail -f /dev/ttyUSB0 >> gsm.txt &
   temp=`gawk '/^+CSQ/{print gensub(/,.*/,"","g",$2)*2-113;RC=-1;exit} END {exit RC+1}' gsm.txt || echo 0`
   if [ "$temp" -ne "0" ]
   then
   echo $temp
   pkill tail
   break #прерываем цикл
   fi
  fi
done
Заработало. Единственный момент, как закрыть процесс без уведомления:
Цитировать./gsm.sh: line 23:  7261 Завершено      tail -f /dev/ttyUSB0 >> gsm.txt

endru

vic5710, как верно подметил bboymig выше, процессы в таком случае крутятся в фоне без завершения, а это опасно, можно повесить систему даже такими простыми скриптами...
если уж применяете:
tail -f /dev/ttyUSB0 >> gsm.txt &
обязательно нужно смотреть какой pid у процесса! чтобы потом его спокойно убить:
tail -f /dev/ttyUSB0 >> gsm.txt &
mypid=`echo $!`
sleep 2
kill $mypid